- Integer Replacement
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 or n - 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
#method 1
需要一定的数学思维,一般是想不到的,但是某些地方还是很可取的。
这题思路就是:
- 偶数的话,直接砍半,再运算。
- 奇数的话,分两种情况,因为我们的目的是用最少的操作,所以,尾数分01, 和11的奇数要分别考虑:01的情况,需要直接-1,11的情况用+1,变成100然后再做会快很多。
但是这里有个特殊的例子3,是-1的,要特殊处理,这样运算会快。
另外,»>和»的区别在于,»>是无符号位的位移,»是有符号位的位移。
/********************************************************
* 5 二进制表示 101 1二进制 001 5&1 = 1
* 8 二进制表示 1000 1二进制 0001 8&1 = 0
* 在这里发现没? 判断n是否为偶数 1. n%2==0 2. n&1==0
* 判断n是否为奇数 1. n%2==1 2. n&1==1
*/
public int integerReplacement(int n) {
int count = 0;
while(n!=1){
if((n&1)==0){
n = n>>>1;
}
else if(n==3||((n>>>1)&1)==0){
n--;
}
else{
n++;
}
count++;
}
return count;
}
#method 2
通用的解法就是递归,这个只要你想明白这个递归的过程。
同时要注意一点, Integer.MAX_VALUE = 2147483647 如果加1就溢出了.
public int integerReplacement(int n) {
//采用递归的方法 这里注意 Integer.MAX_VALUE = 2147483647 如果加一就溢出了
if(n == Integer.MAX_VALUE){
return 32;
}
if(n==1){
return 0;
}
if((n&1)==0){
return 1+integerReplacement(n/2);
}
else{
return Math.min(1+integerReplacement(n-1), 1+integerReplacement(n+1));
}
}