滑动窗口解决最长连续1问题:while与if逻辑差异排查
滑动窗口中while与if的差异及结果差1的原因
首先明确这个问题的核心逻辑:我们需要维护一个窗口[left, right],保证窗口内翻转0的数量不超过k,以此找到最长的连续1(含翻转后的0)。
为什么while和if不等价?
你误以为while循环只会执行一次,这是错误的——当窗口内0的数量超过k时,可能需要多次移动左边界才能让窗口内的0数量回到≤k的状态。比如数组是[0,0,0,1,1],k=1:当right走到第三个0时,zero_count=3>1,这时候需要连续移动left三次,才能让zero_count降到1,而if语句只能移动一次left,此时窗口内zero_count仍然是2>1,逻辑完全错误。
你的while版本结果差1的原因
你遇到的结果差1,大概率是while循环的代码存在细节错误,而非while本身的问题,常见的错误点有这几个:
- 窗口长度计算少加1:正确的窗口长度是
right - left + 1,如果写成right - left,结果会比正确值小1。 - 左边界移动顺序错误:应该先判断
nums[left]是否为0,若是则减少zero_count,再移动left。如果反过来先移动left再修改计数,会导致zero_count统计错误,进而让窗口收缩过度。 - while循环条件写错:比如写成
while zero_count >= k,会导致左边界多移动一次,窗口被不必要地缩小,结果自然差1。
为什么换成if后结果“修复”了?
这只是巧合——要么你在换if的时候无意中修正了上述细节错误(比如把窗口长度的计算改对了),要么你的测试用例刚好没有触发需要多次移动左边界的场景,if只移动一次左边界的错误逻辑刚好蒙对了结果。但if的写法本质是错误的,换一个需要多次收缩左边界的测试用例(比如上面提到的[0,0,0,1,1],k=1),if版本会直接输出错误结果。
正确的while循环示例
def longestOnes(nums, k): left = 0 max_len = 0 zero_count = 0 for right in range(len(nums)): if nums[right] == 0: zero_count += 1 # 当0的数量超过k时,持续收缩左边界直到符合要求 while zero_count > k: if nums[left] == 0: zero_count -= 1 left += 1 # 计算当前窗口长度并更新最大值 max_len = max(max_len, right - left + 1) return max_len
内容的提问来源于stack exchange,提问作者Siggyweb
相关产品推荐
相关产品推荐

