LeetCode疑似Bug:C语言do/while循环假条件下无法退出
问题分析与修复方案
核心问题
你的代码存在几个关键错误,导致循环无法按预期退出,其中最致命的是变量未初始化和错误的二分逻辑:
1. ret变量未初始化
第一次进入do-while循环时,ret没有被赋值,执行ret = (low-hight==1)? ret+1 : (hight+low)/2;会使用内存中的垃圾值。本地环境可能凑巧让垃圾值符合预期,但LeetCode的执行环境中,垃圾值会导致后续所有计算逻辑混乱,这就是为什么第三次迭代明明满足退出条件,循环却继续执行的根本原因。
2. 错误的ret计算逻辑
- 判断条件
low-hight==1完全颠倒,应该是hight - low == 1(因为hight是上界,low是下界,当两者差值为1时,说明边界已收敛)。 - 差值为1时的处理逻辑错误,此时
hight就是第一个错误版本,不需要用ret+1。
3. 非法调用isBadVersion(0)
当ret=1时,ret-1=0,但题目中版本序列是从1开始的,传入0给API会返回不可预期的结果,干扰判断逻辑。
4. 冗余的退出条件判断
你通过bad_1和bad的组合判断退出,虽然逻辑本身没错,但由于前面的计算错误,这个条件根本无法被正确触发。
修复后的代码
使用标准二分查找实现,既能保证最少的API调用次数,又避免了上述所有问题:
// The API isBadVersion is defined for you. // bool isBadVersion(int version); int firstBadVersion(int n) { int left = 1; // 版本从1开始,避免传入0 int right = n; while (left < right) { // 用left + (right-left)/2代替(left+right)/2,避免整数溢出 int mid = left + (right - left) / 2; if (isBadVersion(mid)) { right = mid; // mid是错误版本,目标在[left, mid]区间 } else { left = mid + 1; // mid是正确版本,目标在[mid+1, right]区间 } } return left; // 当left==right时,就是第一个错误版本 }
修复说明
- 初始化
left为1,完全符合题目中版本序列从1开始的要求,避免调用isBadVersion(0)。 - 采用
left + (right-left)/2计算中间值,避免left+right可能导致的整数溢出(比如n为2^31-1时,left+right会超出int的范围)。 - 二分逻辑简洁清晰:每次根据
isBadVersion的结果收缩查找区间,直到左右边界重合,此时就是第一个错误版本,无需额外判断,最大程度减少API调用次数。
内容的提问来源于stack exchange,提问作者TKingu
相关产品推荐
相关产品推荐

