Python编写LeetCode两数和题解时列表意外修改问题排查
问题描述
我是编程新手,近期开始练习LeetCode题目,在编写twoSum题目的Python解法时,无法理解为什么执行到第二个if语句分支时列表发生了意外变更,相关实现代码如下:
class Solution(object): def twoSum(self, nums, target): """ :type nums: List[int] :type target: int :rtype: List[int] """ for x in nums: y = 0 y = target - x if y in nums: if x == y: try: number_index = nums.index(x) del nums[number_index] return [number_index, (nums.index(y)+1)] except: continue elif nums.index(y) != nums.index(x): return [nums.index(x), nums.index(y)]

原因说明
列表发生变更的核心原因是你在x == y的判断分支中主动执行了del nums[number_index]语句。
Python中列表是可变引用类型,函数接收到的nums参数是原始列表的引用,不是列表的独立副本,只要在函数内部对nums执行删除、修改元素的操作,原始传入的列表就会被直接改动。只要代码运行过程中走到过这个分支执行了del操作,哪怕后续没有触发return、走到了其他分支,列表的修改也已经生效了。
另外你当前的写法本身还有几个明显的逻辑问题:
- 反复调用
nums.index(x)只会返回第一个匹配值的下标,遇到重复元素时很容易取错位置,且每次index查询都是O(n)时间复杂度,整体运行效率很低。 - 删除元素后靠
下标+1修正结果的逻辑鲁棒性很差,只有删除的是第一个匹配元素时结果才正确,其他场景都会返回错误下标。 - 裸写
except捕获所有异常会隐藏真正的代码错误,不利于调试。
参考优化写法
不需要修改原列表,用字典存储已经遍历过的元素和对应下标,一次遍历即可得到结果,时间复杂度O(n):
class Solution(object): def twoSum(self, nums, target): """ :type nums: List[int] :type target: int :rtype: List[int] """ num_record = {} for idx, num in enumerate(nums): rest = target - num if rest in num_record: return [num_record[rest], idx] num_record[num] = idx
内容的提问来源于stack exchange,提问作者tehckosong
相关产品推荐
相关产品推荐

