array
math
]
Leetcode 0442. Find All Duplicates in an Array
https://leetcode.com/problems/find-all-duplicates-in-an-array
Solution 1: rearragne numbers
If we are not allowed to use additional memory, the only memory we can use is our original list nums. Let us try to put all numbers on they own places, by this I mean, we try to up number k to place k-1.
Let us iterate through numbers, and change places for pairs of them, if it is needed. Consider and example [4, 3, 2, 7, 8, 2, 3, 1]:
- We look at first number
4and change it with number, which is on the place with number4-1, so we have[7, 3, 2, 4, 8, 2, 3, 1],i = 0. - We still look at first number and now we put it to place
7-1:[3, 3, 2, 4, 8, 2, 7, 1],i = 0. - We still look at first number and now we put it to place
3-1:[2, 3, 3, 4, 8, 2, 7, 1],i = 0. - We still look at first number and now we put it to place
2-1:[3, 2, 3, 4, 8, 2, 7, 1],i = 0. Now, if we look at first place, we see number3, which we need to put on place, where we already have number3. So, we stop withi = 0. - Continue with
i = 1, 2, 3and see that number is already on its place, so we do nothin. - For
i = 4, we do:[3, 2, 3, 4, 1, 2, 7, 8]. - Still,
i = 4, we do:[1, 2, 3, 4, 3, 2, 7, 8], we stop here, becausenums[4] = 3but number3is already on place3-1. - We continue with
i = 5, 6, 7and do nothing
Finally, what we need to do with obtained array: find all places with wrong numbers and return these places, here it is numbers 3 and 2: [1, 2, 3, 4, 3, 2, 7, 8].
Complexity: time complexity O(n), because with each swap on numbers, we put at least one of them on its place. Additional space complexity is O(1).
class Solution(object):
def findDuplicates(self, nums):
for i in range(len(nums)):
while i != nums[i] - 1 and nums[i] != nums[nums[i]-1]:
nums[nums[i]-1], nums[i] = nums[i], nums[nums[i]-1]
return [nums[it] for it in range(len(nums)) if it != nums[it] - 1]
Solution 2: hash numbers
Actually, there is more clean, but much more tricky solution, where we again change our nums, but in different way. Let us again go through the same example and see how it works:
- First, we look at number
4, look at place number3, see, that number there is positive, it means, we did not met number4yet, so we just change sign and have:nums = [4, 3, 2, -7, 8, 2, 3, 1],ans = []. - Similarly, we look at next number
3and change sign of number in cell3-1:nums = [4, 3, -2, -7, 8, 2, 3, 1],ans = []. - Continue with next number, which is
-2now. Number is negative, but what we are interested in isnums[2-1], which is3, so we change its sign and havenums = [4, -3, -2, -7, 8, 2, 3, 1],ans = []. - Next number is
-7, so we havenums = [4, -3, -2, -7, 8, 2, -3, 1],ans = []. - Next number is
8, so we havenums = [4, -3, -2, -7, 8, 2, -3, -1],ans = []. - Next number is
2, we look at place with number2-1 = 1and see, that we have there negative number. It means, that we already seen number2before, so it is duplicate, and we add it to our answer:nums = [4, -3, -2, -7, 8, 2, -3, -1],ans = [2]. - Next number is
-3, so we look at cell with number3-1, where we see negative number, so we see number3before, we update:nums = [4, -3, -2, -7, 8, 2, -3, -1],ans = [2, 3]. - Finally, we see number
-1, so we change sign of number with index1-1:ans = [-4, -3, -2, -7, 8, 2, -3, -1],ans = [2, 3].
Complexity: again, time complexity is O(n), because we iterate once over our nums, space complexity is O(1).
class Solution(object):
def findDuplicates(self, nums):
ans = []
for num in nums:
if nums[abs(num)-1] < 0:
ans.append(abs(num))
else:
nums[abs(num)-1] *= -1
return ans
If you like the solution, you can upvote it on leetcode discussion section: Problem 0442