为何这段整数数组全排列代码可正常运行?看似会下标越界
问题:全排列代码为何没有下标越界?
def permute(self, nums: List[int]) -> List[List[int]]: res = [] perm = [] def dfs(i): if len(nums) == 0: res.append(perm[:]) return for j in range(len(nums)): perm.append(nums[j]) n = nums.pop(j) dfs(i+1) perm.pop() nums.insert(j,n) dfs(0) return res
该函数能够输出正确结果,但从逻辑判断nums[j]本应出现下标越界情况,为何这段代码仍可正常运行?请解释其原理。
这代码之所以不会触发下标越界,核心是循环范围基于每次迭代时nums的实时长度生成,且对nums的修改都在递归回溯的闭环内完成,全程没有用无效索引访问数组:
- 每次进入
for j in range(len(nums))时,range(len(nums))会基于当前nums的长度生成固定的合法索引范围。比如初始nums长度为3,循环的j会取0、1、2,这三个值都是当前数组的有效下标,访问nums[j]自然不会越界。 - 执行
nums.pop(j)时,虽然数组长度会减1,但这一步是在nums[j]已经被读取并加入perm之后才做的——当前j对应的元素已经被安全获取,后续的数组长度变化不会影响这一步的合法性。 - 递归返回后,代码会通过
nums.insert(j,n)把元素插回原位置,让nums的长度恢复到当前循环开始时的状态,不会干扰下一轮循环的j值(因为循环的j范围是一开始就确定的,后续数组长度变化不会改变已经生成的索引序列)。
简单来说,每一轮循环的j都是当前数组的合法索引,且对数组的修改都做了“复原”操作,全程没有出现用过期索引访问数组的情况,所以不会触发下标越界。
内容的提问来源于stack exchange,提问作者beaglul
相关产品推荐
相关产品推荐

