1 题目
Given a positive integer n and you can do operations as follow:
- If n is even, replace n with
n/2
. - If n is odd, you can replace n with either
n + 1
orn - 1
.
What is the minimum number of replacements needed for n to become 1?
Example 1:
Input:
8
Output:
3
Explanation:
8 -> 4 -> 2 -> 1
Example 2:
Input:
7
Output:
4
Explanation:
7 -> 8 -> 4 -> 2 -> 1
or
7 -> 6 -> 3 -> 2 -> 1
2 尝试解
2.1 分析
对于一个奇数,只能通过加减1先变为偶数再说,所以f(2n+1) = min(f(2n),f(2n+2))+1。对于一个偶数,变为1最好的方法就是直接除2,可以最快缩短与2^N之间的距离。
最开始我的想法是,从底向上,求出1-N之间所有数的最少次数。每次去2^N+1 ~ 2^(N+1)区间,求法同上,但是会有大量不需要的计算和存储。所以改为自顶向下。
2.2 代码
class Solution {
public:
map<int,long int> record;
int integerReplacement(long int n) {
if(n == 1) return 0;
record[1] = 0;
record[2] = 1;
return find(n);
}
long int find(long int n){
if(record.count(n)) return record[n];
if(n % 2 == 0) record[n] = find(n/2)+1;
else record[n] = min(find(n-1),find(n+1))+1;
return record[n];
}
};
3 标准解
int integerReplacement(int n) {
int dp[n + 1]; memset(dp, 0, sizeof(dp));
for (int i = 2; i <= n; i++) {
dp[i] = 1 + (i & 1 == 0 ? dp[i / 2] : min(dp[i - 1], 1 + dp[i / 2 + 1]));
}
return dp[n];
}