This is a question from LeetCode #217. Given an integer array nums, return True if any value appears at least twice in the array, and return False if every element is distinct.
And this is my code. I don't understand why it is wrong when the list has no duplicates?
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
CodePudding user response:
This approach prevents duplicative tests and do not require sorting
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]))
CodePudding user response:
You had to increase the value of i variable in each iteration. Also, your repeat loop should not be repeated more than the number of cells in the list.
I add i =1 and change while i < len(nums) 1: to while i < len(nums)-1:
change your code to this:
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
i =1
return b
input:
[1,2,3,4,5,6,7]
output:
False
input:
[1,2,3,4,5,6,4]
output:
True
CodePudding user response:
Here is an approach that might help:
Increment the counter i after every False outcome (in your else
statement)
Have the system check until len(nums)-1 (instead of
len(nums) 1) so that we avoid an index out of range error in the check 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
Results:
containsDuplicate([1, 2, 3])
False
containsDuplicate([1, 2, 2, 3])
True
Alternate approaches:
This is also an alternate approach that is simpler and potentially easier to understand if you know that Python set() (link to set documentation) cannot contain any duplicates. Thus converting the list nums to a set will remove duplicates automagically and then converting the set back to a list will allow you to compare the two lists. If they are NOT the same, then you know the original list had a duplicate:
def containsDuplicates(nums):
return nums != list(set(nums))
containsDuplicates([1, 2, 3])
False
containsDuplicates([1, 2, 2, 3])
True
NOTE: the approach using the set() is substantially faster:
%%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)
CodePudding user response:
This solution is wrong because:
- it causes out of bounds exceptions on good scenario input
- does't check for empty input and will cause an out of bound exception
- iterates incorrectly never updating the loop counter
Finally, it has design issues:
- side effects (sorts input w/o copying)
- useless code (b, setting it to either True or False in the loop even though False was default and True uses early return)
- wraps the solution into a useless class
