题目描述:
给定一个正整数 n,你可以做如下操作:
- 如果 n 是偶数,则用 n / 2替换 n。
- 如果 n 是奇数,则可以用 n + 1或n - 1替换 n。
n 变为 1 所需的最小替换次数是多少?
示例 1:
输入:
8
输出:
3
解释:
8 -> 4 -> 2 -> 1
示例 2:
输入:
7
输出:
4
解释:
7 -> 8 -> 4 -> 2 -> 1
或
7 -> 6 -> 3 -> 2 -> 1
思考从1–>n但是下面这个代码当非常大时会溢出,这个很头疼…
使用动态规划,即1–>0 2–>1 4 —> 2,因此就可以确定3是2,以此类推
代码:
class Solution {
public int integerReplacement(int n) {
if(n == 1){
return 0;
}
if(n == 2){
return 1;
}
Map<Integer, Integer> map = new HashMap<>();
int time = 0;
int tem = 1;
map.put(tem, time);
if(tem == n){
return time;
}
for (int i = 1; i <= n; i++) {
if(map.containsKey(i)){
map.put(i * 2, map.get(i) + 1);
continue;
}else {
map.put(i, Math.min(map.get(i - 1), map.get(i + 1)) + 1);
map.put(i * 2, map.get(i) + 1);
}
}
return map.get(n);
}
}
使用递归,你需要固定一个max为2147483647 返回的是32,否则内存同样溢出
class Solution {
public int integerReplacement(int n) {
//使用递归,2019年7月12日09:18:59
if(n == 1){
return 0;
}
if(3 == n) return 2;
if(2147483647 == n) return 32;
if((n & 1 )== 0){
return 1 + integerReplacement(n >> 1);
}else {
return 1 + Math.min(integerReplacement(n + 1),integerReplacement(n - 1));
}
}
}
本题是属于位运算,因此还是考虑使用位运算来解决
考虑:如果n是偶数,那么就>>1,如果n是奇数,那么-1还是+1取决于,-1或者+1后的数字是偶数之后变成奇数的次数,比如以11B结尾和01B结尾,那么就是要+1,因为11B+1后变成了00B,这样可能除以2的次数就多一些,当然3这个数字除外,有点特殊。
代码:还是同样的问题对于2147483647 同样要返回的是32
class Solution {
public int integerReplacement(int n) {
if(n == 1){
return 0;
}
if(3 == n)
return 2;
int count = 0;
while (n != 1) {
if(2147483647 == n){
return 32;
}
if((n & 1) == 0){
n = n >> 1;
count ++;
continue;
}
if(n == 3){
count += 2;
break;
}
if((n & 3) == 3){
n ++;
}else {
n --;
}
count ++;
}
return count;
}
}