Create 397. Integer Replacement.md

This commit is contained in:
ShusenTang 2020-01-28 21:08:38 +08:00 committed by GitHub
parent 50e79d5e53
commit 16099c8e8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -0,0 +1,44 @@
# [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_map<int, int>cache;
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;
}
};
```