397. Integer Replacement
1. Question
Given a positive integer n, you can apply one of the following operations:
- If
n
is even, replace n withn / 2
. - If
n
is odd, replace n with eithern + 1
orn - 1
.
Return the minimum number of operations needed for n
to become 1
.
2. Examples
Example 1:
Input: n = 8
Output: 3
Explanation: 8 -> 4 -> 2 -> 1
Example 2:
Input: n = 7
Output: 4
Explanation: 7 -> 8 -> 4 -> 2 -> 1
or 7 -> 6 -> 3 -> 2 -> 1
Example 3:
Input: n = 4
Output: 2
3. Constraints
- 1 <= n <= 231 - 1
4. References
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/integer-replacement 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
5. Solutions
5.1. 朴素的实现
这里有个坑,231-1+1在int下会溢出。
class Solution {
public int integerReplacement(int n) {
return toOne((long) n);
}
private int toOne(long n) {
if (n == 1) {
return 0;
}
if (n % 2 == 0) {
return toOne(n / 2) + 1;
} else {
return Math.min(toOne(n + 1), toOne(n - 1)) + 1;
}
}
}
5.2. 用上二进制实现
判断是否是基数可以用与运算,偶数除以2可以用位移替代。
class Solution {
public int integerReplacement(int n) {
return toOne((long) n);
}
private int toOne(long n) {
if (n == 1) {
return 0;
}
if ((n & 1) == 0) {
return toOne(n >> 1) + 1;
} else {
return Math.min(toOne(n + 1), toOne(n - 1)) + 1;
}
}
}
5.3. 将Math.min细化
发现(n + 1) / 2
与(n - 1) / 2
中只有一个可以得到偶数,然鹅得到奇数的话需要加减,多一个步骤,所以可以细化判断。需要剔除n = 3
这个特例(最后结果是1)。
最后得到一个接近双百的结果。
6. Accepted
- 47/47 cases passed (0 ms)
- Your runtime beats 100 % of java submissions
- Your memory usage beats 94.08 % of java submissions (34.9 MB)
class Solution {
public int integerReplacement(int n) {
return toOne((long) n);
}
private int toOne(long n) {
if (n == 1) {
return 0;
}
if ((n & 1) == 0) {
return toOne(n >> 1) + 1;
} else {
if (n == 3) {
return 2;
} else if ((((n + 1) >> 1) & 1) == 0) {
return toOne(n + 1) + 1;
} else {
return toOne(n - 1) + 1;
}
}
}
}