题目:整数替换
给定一个正整数 n ,你可以做如下操作:
- 如果
n**是偶数,则用n / 2替换n**。 - 如果
n**是奇数,则可以用n + 1或n - 1替换n。
返回 n **变为 1 所需的 最小替换次数 。
示例 1:
输入: n = 8
输出: 3
解释: 8 -> 4 -> 2 -> 1
示例 2:
输入: n = 7
输出: 4
解释: 7 -> 8 -> 4 -> 2 -> 1
或 7 -> 6 -> 3 -> 2 -> 1
示例 3:
输入: n = 4
输出: 2
提示:
解题思路
从题目上可以看到,从n到1有两种路线,如果是偶数,即每次除以2,如果是奇数,则需要找n+1和n-1哪种情况需要的操作次数更小,所以可以自顶向下去搜索,寻找最小操作次数,同时可以打表记录一些已经重复搜索过的值。
根据题意可得需要求将n转为1得最小替换次数,分两种情况
n为偶数,只有一种替换方式 将n转为n/2 n为奇数,有两种替换方式,将n转为n-1或n+1,这两种替换方式需要选择较小的那一种 base case : 当已经转化到1时不需要再转化
使用备忘录来记录已经得到过的值,因为n取值为1<n<=Integer.MAX_VALUE,所以还需要考虑当n=Integer.MAX_VALUE时只有一种转化方式,就是n=n-1,否则超出int范围。
将实际比较的数据单位变成Long 传递过来的值小于或等于1时结果为0 如果传递过来的值已经在map集合中存储了,则直接返回结果。
代码实现
private Map < Integer, Integer > cache;
public int integerReplacement(int n) {
cache = new HashMap < > ();
return dfs(n);
}
private int dfs(int n) {
if (n == 1) {
return 0;
}
if (cache.containsKey(n)) {
return cache.get(n);
}
if ((n & 1) == 1) {
cache.put(n, Math.min(dfs(n / 2 + 1), dfs(n / 2)) + 2);
} else {
cache.put(n, dfs(n / 2) + 1);
}
return cache.get(n);
}
运行结果
复杂度分析
- 空间复杂度:O(1)
- 时间复杂度:O(n)
在掘金(JUEJIN) 一起分享知识, Keep Learning!