【问题标题】:Why this solution is wrong?为什么这个解决方案是错误的?
【发布时间】:2022-01-22 12:22:36
【问题描述】:

这是来自 LeetCode #217 的问题。给定一个整数数组nums,如果任何值在数组中至少出现两次,则返回True,如果每个元素都是不同的,则返回False。 这是我的代码。我不明白为什么列表没有重复时会出错?

class Solution:
     def containsDuplicate(self, nums: List[int]) -> bool:
        nums.sort()
        b = False
        i = 0
        while i < len(nums) + 1:
            if nums[i] == nums[i+1]:
                b = True
                return b
            else:
                b = False
        return b

【问题讨论】:

  • i 永远不会更新。如果nums 是[1,2,3],它只会不断检查nums[0]
  • len(nums) != len(set(nums)) 怎么样?
  • while 条件也会导致检查 num[i+1] 越界。对于 5 个元素的列表,while 循环将以 i == 5 执行,从而导致 if 检查 nums[6](超出范围)。
  • 如果只有一些元素被欺骗,你会返回什么?
  • 尝试用 print 替换 while 循环中的返回值。非常适合调试。

标签: python arrays duplicates


【解决方案1】:

这是一种可能有帮助的方法:

在每个False 结果之后增加计数器i(在您的else 声明)

让系统检查直到len(nums)-1(而不是 len(nums)+1) 这样我们就可以避免检查 index out of range error nums[i+1]

def containsDuplicate(nums):
       nums.sort()
       b=False
       i=0
       while i<(len(nums)-1):
           if nums[i]==nums[i+1]:
               b=True
               return b
           else:
               b=False
               i += 1
       return b

结果:

containsDuplicate([1, 2, 3])
False

containsDuplicate([1, 2, 2, 3])
True

替代方法:

如果您知道 Python set() (link to set documentation) 不能包含任何重复项,这也是一种更简单且可能更容易理解的替代方法。因此,将列表nums 转换为集合将自动删除重复项,然后将集合转换回列表将允许您比较两个列表。如果它们不相同,那么您知道原始列表有重复:

def containsDuplicates(nums):
    return nums != list(set(nums))

containsDuplicates([1, 2, 3])
False

containsDuplicates([1, 2, 2, 3])
True

注意:使用set() 的方法要快得多:

%%timeit
containsDuplicates(list(range(10000))+[9999])   # set version

306 µs ± 9.84 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%%timeit
containsDuplicate(list(range(10000))+[9999]).   # sorted item-wise comparison

1.79 ms ± 13.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

【讨论】:

  • 为什么重复之前给出的答案?
  • @SaeedEmamYari 你和我同时写下我们的答案。直到我提交答案后,我才看到您的答案。道歉。我经常草拟快速答案并发布它们,然后回来编辑更多细节,以便未来的读者有更多的背景。
【解决方案2】:

这种方法可以防止重复测试并且不需要排序

def contains_duplicate(nums: list) -> bool:
    for pos1, value in enumerate(nums):
        for pos2 in range(pos1+1, len(nums)):
            res = value + nums[pos2]
            if value == nums[pos2]:
                return True
    return False

print(contains_duplicate([1, 2, 3, 4, 3, 5]))

【讨论】:

    【解决方案3】:

    这个解决方案是错误的,因为:

    • 它会在良好的场景输入上导致超出范围的异常
    • 不检查空输入,会导致越界异常
    • 错误地迭代从不更新循环计数器

    最后,它有设计问题:

    • 副作用(对输入进行排序,无需复制)
    • 无用的代码(b,在循环中将其设置为 True 或 False,即使默认为 False 并且 True 使用提前返回)
    • 将解决方案包装到一个无用的类中

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-26
      • 1970-01-01
      • 1970-01-01
      • 2021-05-20
      • 2016-06-22
      • 2018-02-20
      • 1970-01-01
      相关资源
      最近更新 更多