[leetcode 1611][Go][位运算][记忆化搜索]使整数变为 0 的最少操作次数

[leetcode 1611][Go][位运算][记忆化搜索]使整数变为 0 的最少操作次数
inkOrCloud题目链接
解题思路
递归(超时)
根据题目得知,要将数n变为0,那只能从左往右将所有为1的位数翻转。设i为下标从左往右遍历,若第i为为1则进行翻转,翻转时无论第i位为1还是0都需要分为以下三种情况处理:
- 若i为0则直接翻转
- 若i大于0且i-1为0则先递归处理将i-1翻转为1,翻转后再按照下面的情况处理
- 若i大于0且i-1为1则设j = [i-2, 0],遍历j,若第j位为1则先递归翻转第j位
根据以上子问题就可以初步构建递归函数:
1 | //判断第i位是否为0 |
然后在主函数中循环翻转最左侧的1直到n为0即可: 1
2
3
4
5
6
7var ret int
for n != 0 {
d, m := reverse(n, bits.Len(uint(n))-1)
ret += d
n = m
}
return ret
记忆化搜索
因为翻转i只会影响[i, 0]上的位数,那么就可以在每次递归时将[i,
0]上的数字和i记录下来,这样在之后的递归中遇到相同的情况就能在O(1)时间内拿到结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42//key[0]表示[i, 0]位上的数, key[1]表示i
//value[0]表示翻转需要的操作数,value[1]表示翻转后[i, 0]位的数
var hash = make(map[[2]int][2]int)
var reverse func(n int, i int) (int, int)
reverse = func(n, i int) (int, int) {
if i == 0 && isZero(n, 0) {
return 1, n + 1
} else if i == 0 {
return 1, n - 1
}
//提取[i, 0]位并查询
if m, ok := hash[[2]int{n & (1<<(i+1) - 1), i}]; ok {
//若有记录,则将[i,0]重置为0再将m覆盖到[i,0]位
n &= (1<<bits.Len(uint(n)) - 1) - (1<<(i+1) - 1)
n |= m[1]
return m[0], n
}
var ret int
//因为后面的翻转操作会导致[i,0]位变化所以提前记录key
var key = [2]int{n & (1<<(i+1) - 1), i}
if isZero(n, i-1) {
d, m := reverse(n, i-1)
ret += d
n = m
}
for j := i - 2; j >= 0; j-- {
if !isZero(n, j) {
d, m := reverse(n, j)
ret += d
n = m
}
}
if isZero(n, i) {
n = 1<<i | n
} else {
n = ((1<<bits.Len(uint(n)) - 1) - (1 << i)) & n
}
ret++
//记录进哈希表
hash[key] = [2]int{ret, n & (1<<(i+1) - 1)}
return ret, n
}
完整代码
1 | func isZero(n int, i int) bool { |

![[leetcode 3321][Go][有序集合]计算子数组的 x-sum II](https://s3.inkorcloud.top/image/2025/11/c9f55b2ecb04d16a57547b9f4de294ef.png)
![[leetcode 2589][Go][贪心]完成所有任务的最少时间](https://s3.inkorcloud.top/image/2025/11/b966fd1a91aa1ea098b86e6d778523c2.png)
![[leetcode 3234][Go]统计1显著的字符串的数量](https://s3.inkorcloud.top/image/2025/11/a72a47911de291f51cbb5902e4811c1f.png)
![[leetcode 2528][Go][二分答案][差分数组][前缀和]最大化城市的最小电量](https://s3.inkorcloud.top/image/2025/11/fa0013722d9361b4383839722394dcf2.png)