题意
给一个数n,对其操作使用最少的步数将n变成1。
操作:
- n为偶数,n / 2
- n为奇数,可以n + 1或者n - 1
思路
我们贪心的去考虑,当n比较大的时候,我们将n减小一半一定比n - 1要优。怎么尽量维持更多的减半操作呢?
当n是偶数的时候,一定是n / 2。
当n为奇数的时候,假设我们 n=2k+1 :
- n+1 后减半: n=((2k+1)+1)/2=k+1
- n−1 后减半: n=((2k+1)−1)/2=k
如果要使下一次也尽量能够减半的话,即对n操作后的数应该为偶数。
所以,当 k 为奇数时,
k+1 为偶数,我们选择 n+1当 k 为偶数时,我们选择
n−1
这是在n比较大的情况下,减半一定比减1更优,当我们n接近于1的时候,不一定是这样。
我们计算可知:当n == 3的时候,我们应该选择 n−1
代码
class Solution {
public:
int integerReplacement(long long n) {
int s = 0;
while (n != 1) {
if (n & 1) {
if (n == 3) n--;
else {
int k = n / 2;
if (k & 1) n++;
else n--;
}
} else {
n >>= 1;
}
s++;
}
return s;
}
};