为何元素数大于3的列表输入会触发list index out of range错误?
问题排查与修复
错误原因
- 循环范围缺失导致空列表访问:
best_sort中for i in range(1, len(arr)-1)的范围错误。当数组长度为2时,len(arr)-1 = 1,range(1,1)无迭代项,flips保持为空,后续访问flips[0]触发IndexError。 - 原地修改数组的副作用:
wenden直接操作原数组,递归过程中后续迭代会使用被修改后的数组,破坏逻辑一致性。 - 递归结果嵌套错误:使用
append添加递归返回的列表,导致最终序列是嵌套结构(如[[2, [1]]]),而非扁平的操作序列。 - 最短序列遍历范围错误:
for i in range(1, len(flips)-1)未遍历所有候选序列,可能错过真正的最短操作序列。
修复方案
1. 修正循环范围
将循环范围改为range(1, len(arr)),确保数组长度为2时仍能执行迭代,避免flips为空。
2. 避免原地修改数组
在wenden中创建数组副本进行操作,防止原数组被递归过程意外修改:
def wenden(arr, n): # dreht die Ersten n elemente um arr_copy = arr.copy() i = 0 while i < n // 2: arr_copy[i], arr_copy[n - i - 1] = arr_copy[n - i - 1], arr_copy[i] i += 1 arr_copy.pop(0) return arr_copy
3. 扁平拼接递归结果
使用extend替代append,将递归返回的操作序列直接合并到当前列表中,避免嵌套:
flipi.extend(best_sort(sort_lis))
4. 完整遍历候选序列
遍历整个flips列表寻找最短序列,同时添加空列表判断作为兜底:
if not flips: return [] ret = 0 for i in range(1, len(flips)): if len(flips[i]) < len(flips[ret]): ret = i
修复后的完整代码
def wenden(arr, n): # dreht die Ersten n elemente um arr_copy = arr.copy() i = 0 while i < n // 2: arr_copy[i], arr_copy[n - i - 1] = arr_copy[n - i - 1], arr_copy[i] i += 1 arr_copy.pop(0) return arr_copy def ist_Sortirt(arr): for i in range(len(arr) - 1): if arr[i] > arr[i+1]: return False return True def best_sort(arr): flips = [] if not ist_Sortirt(arr): for i in range(1, len(arr)): sort_lis = wenden(arr, i + 1) flipi = [i+1] flipi.extend(best_sort(sort_lis)) flips.append(flipi) if not flips: return [] ret = 0 for i in range(1, len(flips)): if len(flips[i]) < len(flips[ret]): ret = i return flips[ret] else: return []
测试验证
输入[2,1,3,6],修复后的代码返回[2],符合预期:反转前2个元素得到[1,2,3,6],移除首个元素后得到有序数组[2,3,6],仅需1次操作。
内容的提问来源于stack exchange,提问作者trashy-coder
相关产品推荐
相关产品推荐

