LeetCode 397. 整数替换
397. 整数替换
Solution
思路:BFS
或者DFS
,但是最大范围是2^31-1
,会超出int
的最大范围。还可以进行记忆化搜索。题解中面对奇数的情况,可以等效为2步到达偶数,即\(2+Math.min(dfs(\frac{val +1}{2},dfs(\frac{val-1}{2}))\),这里加一可能越界,所以可以对应变为\(\lfloor\frac{val}{2}\rfloor+1\)、\(\lfloor\frac{val}{2}\rfloor\)。
然后还处理超出范围的小细节。
BFS
class Solution {
public int integerReplacement(int n) {
if (n == 1) return 0;
Queue<Long[]> queue = new LinkedList<>();
queue.add(new Long[]{n * 1L, 0 * 1L});
while (!queue.isEmpty()) {
Long[] t = queue.poll();
Long val = t[0], step = t[1];
if (val == 1) {
return step.intValue();
}
if (val % 2 != 0) {
queue.add(new Long[]{val + 1, step + 1});
queue.add(new Long[]{val - 1, step + 1});
} else {
queue.add(new Long[]{val / 2, step + 1});
}
}
return 0;
}
}
DFS
class Solution {
int ans = Integer.MAX_VALUE;
public int integerReplacement(int n) {
dfs(n * 1L, 0);
return ans;
}
void dfs(Long val, int step) {
if (val == 1) {
ans = Math.min(ans, step);
return ;
}
if (val % 2 == 0) {
dfs(val / 2, step + 1);
} else {
dfs(val + 1, step + 1);
dfs(val - 1, step + 1);
}
}
}
BFS记忆化
class Solution {
public int integerReplacement(int n) {
if (n == 1) return 0;
Map<Long, Integer> map = new HashMap<>();
Queue<Long> queue = new ArrayDeque<>();
queue.add(n * 1L);
map.put(n * 1L, 0);
while (!queue.isEmpty()) {
Long t = queue.poll();
int step = map.get(t);
if (t == 1) {
return step;
}
Long[] ts = t % 2 == 0 ? new Long[]{t / 2} : new Long[]{t + 1, t - 1};
for (int i = 0; i < ts.length; i++) {
if (!map.containsKey(ts[i])) {
queue.add(ts[i]);
map.put(ts[i], step + 1);
}
}
// if (t % 2 != 0) {
// if (!map.containsKey(t + 1)) {
// queue.add(t + 1);
// map.put(t + 1, step + 1);
// }
// if (!map.containsKey(t - 1)) {
// queue.add(t - 1);
// map.put(t - 1, step + 1);
// }
// } else {
// if (!map.containsKey(t / 2)) {
// queue.add(t / 2);
// map.put(t / 2, step + 1);
// };
// }
}
return 0;
}
}
DFS记忆化
class Solution {
Map<Long, Integer> map = new HashMap<>();
public int integerReplacement(int n) {
return dfs(n * 1L);
}
int dfs(Long val) {
if (val == 1) {
return 0;
}
if (map.containsKey(val)) {
return map.get(val);
}
int res = 0;
if (val % 2 == 0) {
res = 1 + dfs(val / 2);
} else {
res = 1 + Math.min(dfs(val + 1), dfs(val - 1));
}
map.put(val, res);
return res;
}
}
数学分析
class Solution {
public int integerReplacement(int n) {
int ans = 0;
while (n != 1) {
if (n % 2 == 0) {
n /= 2;
ans++;
} else if (n % 4 == 1) {
n /= 2;
ans += 2;
} else if (n % 4 == 3){
if (n == 3) {
n = 1;
ans += 2;
} else {
n = n / 2 + 1;
ans += 2;
}
}
}
return ans;
}
}
二进制分析
class Solution {
public int integerReplacement(int _n) {
int ans = 0;
long n = _n;
while (n != 1) {
if (n % 2 == 0) {
n /= 2;
} else {
if (n != 3 && ((n >> 1) & 1) == 1) n++;
else n--;
}
ans++;
}
return ans;
}
}
埋骨何须桑梓地,人生无处不青山