调试时变量满足循环终止条件但while循环未终止且出现索引越界
Python循环未终止与索引越界问题分析
问题现象
调试代码时发现,即便i+j等于len(fruits),外层while (i + j) != len(fruits):循环仍未终止,还触发了索引越界错误。
完整代码
from typing import List class Solution: def totalFruit(self, fruits: List[int]) -> int: pointed = [0 for i in range(max(fruits) + 1)] maX, count = 0, 0 count_type = 0 i, j = 0, 0 while (i + j) != len(fruits): while count_type < 3: if pointed[fruits[i + j]] == 0: count_type += 1 if count_type < 3: count += 1 pointed[fruits[i + j]] += 1 j += 1 elif count_type < 3 and pointed[fruits[i + j]] != 0: pointed[fruits[i + j]] += 1 count += 1 j += 1 if count > maX: maX = count if pointed[fruits[i]] == 1: count_type -= 2 pointed[fruits[i]] -= 1 count -= 1 i += 1 j-= 1 return maX fruits = input() fruits = [int(i) for i in fruits.split()] obj = Solution() print(obj.totalFruit(fruits))
问题根源
- 循环终止条件失效:外层循环仅判断
i+j != len(fruits),但内层循环可能在i+j等于数组长度后继续递增j,导致i+j超过数组长度,此时条件依然成立,循环无法终止。 - 内层循环逻辑漏洞:当
count_type增加到3时,没有停止j的递增,后续仍会尝试访问fruits[i+j],直接触发索引越界。 - 边界判断缺失:整个逻辑中没有对
i+j是否超出数组长度做检查,无限制的j递增必然导致越界。
修复方案
方案1:完善原逻辑的边界判断
给内层循环加上数组长度限制,同时调整外层循环条件确保正常终止:
from typing import List class Solution: def totalFruit(self, fruits: List[int]) -> int: if not fruits: return 0 pointed = [0 for i in range(max(fruits) + 1)] maX, count = 0, 0 count_type = 0 i, j = 0, 0 n = len(fruits) while i < n: # 内层循环增加数组长度判断,避免越界 while i + j < n and count_type < 3: fruit = fruits[i + j] if pointed[fruit] == 0: count_type += 1 if count_type <= 2: count += 1 pointed[fruit] += 1 j += 1 else: # 种类达3种,停止扩展 break else: pointed[fruit] += 1 count += 1 j += 1 maX = max(maX, count) # 收缩左边界 left_fruit = fruits[i] if pointed[left_fruit] == 1: count_type -= 1 pointed[left_fruit] -= 1 count -= 1 i += 1 j -= 1 # 处理窗口收缩为空的情况 if j < 0: j = 0 count_type = 0 pointed = [0 for _ in range(max(fruits) + 1)] return maX fruits = input() fruits = [int(i) for i in fruits.split()] obj = Solution() print(obj.totalFruit(fruits))
方案2:改用标准滑动窗口实现(更简洁高效)
用双指针直接维护窗口左右边界,避免嵌套循环的逻辑混乱:
from typing import List class Solution: def totalFruit(self, fruits: List[int]) -> int: fruit_count = {} left = 0 max_len = 0 for right in range(len(fruits)): fruit = fruits[right] fruit_count[fruit] = fruit_count.get(fruit, 0) + 1 # 种类超过2种时,收缩左边界 while len(fruit_count) > 2: left_fruit = fruits[left] fruit_count[left_fruit] -= 1 if fruit_count[left_fruit] == 0: del fruit_count[left_fruit] left += 1 # 更新最大窗口长度 max_len = max(max_len, right - left + 1) return max_len fruits = input() fruits = [int(i) for i in fruits.split()] obj = Solution() print(obj.totalFruit(fruits))
说明
第二种方案是滑动窗口问题的标准实现,逻辑更清晰,时间复杂度为O(n),彻底避免了原代码中的边界错误。
内容的提问来源于stack exchange,提问作者nnguyenquy
相关产品推荐
相关产品推荐

