leetcode 2026-02-26 每日一练 - 将二进制表示减到 1 的步骤数

leetcode 2026-02-26 每日一练 - 将二进制表示减到 1 的步骤数
Austoin题目描述
LeetCode 1404. 将二进制表示减到 1 的步骤数
给你一个以二进制形式表示的数字 s。请你返回按下述规则将其减少到 1 所需要的步骤数:
- 如果当前数字为偶数,则将其除以
2 - 如果当前数字为奇数,则将其加上
1
题目保证你总是可以按上述规则将测试用例变为 1。
解题思路
核心观察
对于二进制字符串:
- 偶数:最低位是
0,除以2相当于去掉最后一位 - 奇数:最低位是
1,加1会产生进位,需要找到第一个0并将其变为1,之前的所有1都变为0
方法一:直接模拟
从后往前遍历二进制字符串:
- 如果最低位是
0,直接去掉(相当于除以2) - 如果最低位是
1,执行加1操作:- 从后往前找到第一个
0 - 将这个
0变为1 - 将这个
0之后的所有1都变为0 - 如果没有找到
0(全是1),则在最前面添加一个1
- 从后往前找到第一个
代码实现
方法一:直接模拟
1 | func numSteps(s string) int { |
方法二:进位优化(推荐)
通过观察可以发现:
- 基础步骤:长度为
n的二进制数,至少需要n-1次「除以 2」操作 - 额外步骤:当某一位是
1(且有进位)时,需要额外执行「加 1」操作
1 | func numSteps(s string) int { |
核心细节
方法一
- 切片操作:
bits[:len(bits)-1]去掉最后一位 - 进位处理:从后往前遍历,将连续的
1都变为0 - 边界情况:全是
1时需要在最前面添加1
方法二
- 基础步骤:
len(s) - 1表示除了最高位,每一位都要除以2 - 额外步骤:
sum % 2表示当前位变成1后需要加1 - 进位计算:
(sum + sum%2) / 2计算下一位的进位
复杂度分析
方法一
- 时间复杂度:
O(n²),最坏情况下每次加1都需要遍历整个字符串 - 空间复杂度:
O(n),需要存储字节数组
方法二
- 时间复杂度:
O(n),只需遍历一次字符串 - 空间复杂度:
O(1),只使用常数额外空间
总结
这道题有两种解法:
- 方法一:直接模拟,思路清晰但效率较低
- 方法二:进位优化,通过数学推导简化计算,效率更高
关键理解:
偶数除以
2= 去掉最低位0奇数加
1= 产生进位,影响后续计算总步骤 = 基础步骤 + 额外步骤 + 最高位进位处理
同样的,灵神给的模拟代码,思路一样,但是代码更简洁。
基础步骤:一个长度为n的二进制数(高位在前),要把除最高位外的所有位 “消掉”,至少需要n-1次「除以 2」操作(比如1101(4 位),基础步骤是 3 次,对应把最后 3 位依次除 2);
额外步骤:当某一位是1(且有进位)时,需要额外执行「加 1」操作,而「加 1」会产生新的进位,影响前一位的计算;
最终总步骤 = 基础步骤 + 额外步骤 + 最高位进位的额外处理。
1 | func numSteps(s string) int { |













