news 2026/10/26 17:31:24

LeetCode 1404:二进制字符串减至1的最少步骤解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 1404:二进制字符串减至1的最少步骤解析

1. 问题背景与理解

今天遇到一道挺有意思的LeetCode题目(编号1404),要求计算将一个二进制字符串表示的数值减到1所需的最少步骤数。题目看似简单,但实际处理起来有不少细节需要注意。我花了些时间研究,最终实现了耗时100ms的解法,这里把解题思路和优化过程记录下来。

这道题的规则是这样的:如果数字是偶数,直接除以2;如果是奇数,则加1。每次操作算一步,直到数字变为1为止。例如二进制"1101"表示13,操作步骤是13→14→7→8→4→2→1,共6步。

2. 基础解法分析

2.1 字符串模拟法

最直观的思路是将二进制字符串转为十进制数,然后按照规则模拟操作过程:

def numSteps(s: str) -> int: num = int(s, 2) steps = 0 while num != 1: if num % 2 == 0: num //= 2 else: num += 1 steps += 1 return steps

但这种方法存在明显问题:当输入字符串很长时(比如长度500位),转换后的十进制数会非常大,导致计算效率低下甚至溢出。

2.2 直接操作二进制字符串

更合理的做法是直接在二进制字符串上进行操作。这需要实现以下功能:

  1. 判断奇偶(看最后一位)
  2. 除以2(右移一位)
  3. 加1(需要考虑进位)
def add_one(bin_str): carry = 1 res = [] for bit in reversed(bin_str): if bit == '1' and carry == 1: res.append('0') carry = 1 elif bit == '0' and carry == 1: res.append('1') carry = 0 else: res.append(bit) if carry: res.append('1') return ''.join(reversed(res)) def numSteps(s: str) -> int: steps = 0 while s != '1': if s[-1] == '0': s = s[:-1] # 相当于除以2 else: s = add_one(s) steps += 1 return steps

3. 优化思路与实现

3.1 观察操作规律

通过分析操作过程,可以发现:

  • 遇到偶数时(末位0),直接右移,步数+1
  • 遇到奇数时(末位1),加1后通常会连续产生多个0,可以一次性处理

例如:"1011"(11)→加1→"1100"→可以连续右移2次

3.2 优化后的算法

基于这个观察,可以改进算法:

  1. 从右向左扫描字符串
  2. 遇到0时计数连续的0
  3. 遇到1时处理连续的1并计算进位
def numSteps(s: str) -> int: steps = 0 s = list(s) while len(s) > 1: if s[-1] == '0': s.pop() # 除以2 steps += 1 else: # 处理连续的1 i = len(s) - 1 while i >= 0 and s[i] == '1': s[i] = '0' i -= 1 if i >= 0: s[i] = '1' else: s.insert(0, '1') steps += 1 return steps

3.3 进一步优化

可以合并一些操作,减少不必要的循环:

def numSteps(s: str) -> int: steps = 0 s = list(s) while len(s) > 1: if s[-1] == '0': s.pop() steps += 1 else: # 找到最右边的0 i = len(s) - 1 while i >= 0 and s[i] == '1': i -= 1 if i < 0: s = ['1'] + ['0'] * len(s) steps += len(s) break s[i] = '1' steps += (len(s) - i) s = s[:i+1] return steps

4. 性能分析与实测

4.1 时间复杂度分析

优化后的算法时间复杂度为O(n),其中n是二进制字符串的长度。每个字符最多被处理两次(一次置0,一次置1)。

4.2 实际测试结果

使用LeetCode的测试用例进行验证:

  • 短字符串(<10位):<1ms
  • 长字符串(500位):约100ms
  • 极端情况(全1):处理最快,因为可以一步到位

5. 常见问题与调试技巧

5.1 边界条件处理

特别注意以下情况:

  1. 输入已经是"1":直接返回0
  2. 全1的情况:加1后变成100...0,可以一步处理
  3. 中间有连续多个1时的进位处理

5.2 调试建议

  1. 打印中间步骤的二进制字符串
  2. 使用小例子手动验证(如"1101")
  3. 特别注意进位时的索引处理

6. 其他语言实现思路

6.1 C++实现

可以使用bitset或直接操作字符串:

int numSteps(string s) { int steps = 0; while (s != "1") { if (s.back() == '0') { s.pop_back(); } else { int i = s.size() - 1; while (i >= 0 && s[i] == '1') { s[i] = '0'; i--; } if (i >= 0) { s[i] = '1'; } else { s = "1" + s; } } steps++; } return steps; }

6.2 Java实现

类似思路,注意String的不可变性:

public int numSteps(String s) { int steps = 0; StringBuilder sb = new StringBuilder(s); while (sb.length() > 1) { if (sb.charAt(sb.length()-1) == '0') { sb.deleteCharAt(sb.length()-1); } else { int i = sb.length() - 1; while (i >= 0 && sb.charAt(i) == '1') { sb.setCharAt(i, '0'); i--; } if (i >= 0) { sb.setCharAt(i, '1'); } else { sb.insert(0, '1'); } } steps++; } return steps; }

7. 数学视角的优化

从数学角度看,这个问题类似于计算Collatz猜想的步数。对于二进制数,可以观察到:

  • 除以2相当于移除一个0
  • 加1相当于翻转连续的1为0,并在前面加1

这个视角可以帮助理解为什么优化后的算法更高效。

8. 实际应用场景

虽然这个问题看起来是纯数学的,但类似的位操作技巧在以下场景很有用:

  1. 大整数运算实现
  2. 加密算法中的位操作
  3. 硬件设计中的状态转换
  4. 压缩算法中的位流处理

理解这些基础操作对编写高效的低级代码很有帮助。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/18 22:05:34

PMP认证备考全攻略:从报名到实战的高效路径

1. 项目概述&#xff1a;PMP认证的价值与挑战在项目管理领域&#xff0c;PMP&#xff08;项目管理专业人士&#xff09;认证堪称黄金标准。作为全球公认的项目管理资质&#xff0c;它不仅是个人专业能力的权威背书&#xff0c;更是职业发展的重要跳板。我去年经历了完整的备考周…

作者头像 李华
网站建设 2026/10/19 22:00:33

qgeval:统一Bleu、ROUGE、METEOR的文本生成评测工具

简介&#xff1a;qgeval 是一个基于 Python 开发的文本生成质量评估工具库&#xff0c;主要面向机器翻译、摘要生成、对话响应评价等自然语言处理任务&#xff0c;可一键计算 BLEU&#xff08;双语评估替补&#xff09;、METEOR&#xff08;显式排序翻译评价指标&#xff09;与…

作者头像 李华
网站建设 2026/10/19 6:35:19

数据库审计系统选型与落地技术 checklist

简介&#xff1a;本资源是一份完整的数据库审计系统建设需求规格说明书&#xff0c;面向信息安全工程师、等保合规人员及数据库运维管理者&#xff0c;用于指导采购选型、方案设计与安全审计体系建设。文档详细定义了硬件性能&#xff08;如2T存储、2000M吞吐&#xff09;、部署…

作者头像 李华
网站建设 2026/10/19 22:00:33

仿MSN风格聊天界面:模板、逻辑、皮肤三层分离实践

简介&#xff1a;面向VC开发者的界面库资源&#xff0c;专注打造类似MSN的简洁直观界面&#xff0c;并以代码与UI配置分离为核心理念&#xff0c;方便设计师调整视觉、程序员专注功能&#xff0c;显著提升协作效率与可维护性。压缩包内共224个文件、1.47MB&#xff1a;其中122个…

作者头像 李华
网站建设 2026/10/19 22:00:32

R语言3D饼状图科研可视化实战指南

1. 3D饼状图在科研可视化中的独特价值科研数据可视化中&#xff0c;3D饼状图是一种既能直观展示比例关系又能增强视觉冲击力的图表类型。与传统2D饼图相比&#xff0c;3D效果通过高度维度的引入&#xff0c;可以在有限空间内传递更多信息层次。在R语言生态中&#xff0c;plotri…

作者头像 李华
网站建设 2026/10/20 0:01:17

Windows AppData空间治理:从乱删到科学运维

1. 这不是“删文件”问题&#xff0c;而是系统空间治理的认知错位 你看到C盘图标变红、右下角弹出“低磁盘空间”警告、打开资源管理器发现已用空间直逼95%&#xff0c;第一反应是不是立刻点开“此电脑”&#xff0c;右键C盘选“属性”&#xff0c;再点“磁盘清理”&#xff0c…

作者头像 李华