# [397. Integer Replacement](https://leetcode.com/problems/integer-replacement/) # 思路 给定一个正整数n,然后让我们通过变换变为1,求最小的变换步数。变换定义如下: * 如果n是偶数,变为n/2; * 如果n是奇数,可以变为n+1或者n-1。 所以, * 若n为偶数,`integerReplacement(n) = 1 + integerReplacement(n >> 1);` * 若n为奇数,`integerReplacement(n) = 1 + min(integerReplacement(n - 1), 1 + integerReplacement((n >> 1) + 1));`。 > 注意若n为奇数那么`((n+1) >> 1) == (n >> 1) + 1`,前者当n为INT_MAX时会溢出而后者不会。 一开始我想到用动归,但是发现从前往后更新dp时会很耗时,因为做了很多不必要的计算,所以我们应该从后往前更新dp,也即用递归。 另外,我们可以用一个hash表cache来存放已经计算出来的值避免重复计算。 # 代码 ``` C++ class Solution { private: unordered_mapcache; public: int integerReplacement(int n) { if(n < 2) return 0; if(cache.count(n)) return cache[n]; int res = 0, n_back = n; if(n & 1) res = 1 + min(integerReplacement(n - 1), 1 + integerReplacement((n >> 1) + 1)); else{ // 不断除2直到结果是奇数 while(!(n & 1)){ res += 1; n >>= 1; } res += integerReplacement(n); } cache[n_back] = res; return res; } }; ```