Problems of the same type
One of the problems in Leetcode is to find repeated or missing numbers in array range (0, N)
- Interview question 03. Repeated numbers in array
- Leetcode 41. First positive number missing
- Leetcode 442. Duplicate data in array
- Leetcode 448. Find all missing numbers in the array
The central idea of array hash
Because the values of array elements are all within the specified range, this range is just good enough to correspond to the subscripts of array one by one;
So when you see the value, you can know where it should be placed after sorting
That is to say, after sorting the numbers with size I, they should be in the position with subscript i, which is like writing a hash function
And finding the duplicate number is the hash conflict, or the location where there is no missing is the location
If 0 is useful in an array, you need to replace it step by step
If 0 does not exist or is useless in the array, you only need to record the position of the number with a negative sign
This method can realize in situ replacement
Time complexity: O(N)
Space complexity: O(1)
Example code
Interview question 03. Repeated numbers in array
All numbers in an array nums of length n are in the range of 0 to n-1. Some numbers in the array are repeated, but I don't know how many numbers have been repeated, or how many times each number has been repeated. Please find any duplicate number in the array.
When exchanging nums[i] and nums[nums[i], it should be noted that the value change of nums[i] cannot be exchanged directly. The last sentence of the initial value of nums[i] should be recorded.
class Solution: def findRepeatNumber(self, nums: List[int]) -> int: i = 0 while True: if nums[i] == i: i += 1 continue if nums[i] == nums[nums[i]] : return nums[i] else: tmp = nums[i] nums[i] = nums[nums[i]] nums[tmp] = tmp
Leetcode 41. First positive number missing
To give you an array of unsorted integers, please find out the smallest positive integer that does not appear.
Example: input: [3,4, - 1,1] output: 2
Complexity should be O(n) and only constant level extra space can be used
This problem involves negative numbers. First of all, you need to deal with all the negative numbers before you can sort out the arrays according to the above ideas
Negative sign is from Hashi method. In this problem, we do not need to exchange numbers, but record the position I of the array corresponding to i+1 (negative), because 0 is not considered, this method can be used. If 0 is considered, -0 = 0 will fail.
Finally, the number at the top of the array is not equal to the missing positive number.
But we need to think about this problem further. The array length is n, and the number in the array will be greater than N. how to deal with this situation?
In fact, it's very simple to think about that if the array length is n, then the missing positive range must be in [1,N+1]. So when a number greater than n appears, we can continue directly without handling it.
Processing of negative numbers and numbers with 0 and greater than N: first, judge whether there is 1 in the array, if not, return 1 directly, if there is, process all negative numbers as 1
class Solution: def firstMissingPositive(self, nums: List[int]) -> int: #Processing negative numbers and 0 and numbers greater than N flag = 0 for i in range(len(nums)): if nums[i] == 1: flag = 1 if nums[i] <= 0 or nums[i] > len(nums): nums[i] = 1 if flag == 0: return 1 #Use negative number to record the corresponding position of each number. Finally, only find the position greater than 0 and return the corresponding number for i in range(len(nums)): index = abs(nums[i]) - 1 nums[index] = - abs(nums[index]) for i in range(len(nums)): if nums[i] > 0: return i + 1 return len(nums) + 1
Leetcode 442. Duplicate data in array
Given a n integer array a, where 1 ≤ a[i] < n (n is the length of the array), some elements appear twice while others appear once.
Find all elements that appear twice.
No additional space is needed and the O(n) time complexity.
Input: [4,3,2,7,8,2,3,1] output: [2,3]
Solution 1: according to the idea of hash in place
class Solution: def findDuplicates(self, nums: List[int]) -> int: i = 0 res = [] while i < len(nums): if nums[i] == i + 1: i += 1 continue if nums[i] == i + 1 or nums[i] == nums[nums[i] - 1] : res.append(nums[i]) i += 1 continue else: index = nums[i] - 1 nums[i] = nums[nums[i] - 1] nums[index] = index + 1 return list(set(res))
Solution 2: negative sign self hash
class Solution: def findDuplicates(self, nums: List[int]) -> int: res =[] for i in range(len(nums)): index = abs(nums[i]) - 1 if nums[index] < 0: res.append(index + 1) nums[index] = - abs(nums[index]) return res
Leetcode 448. Find all missing numbers in the array
The same way of thinking as the solution 2 of the previous question
class Solution: def findDisappearedNumbers(self, nums: List[int]) -> List[int]: res =[] for i in range(len(nums)): index = abs(nums[i]) - 1 nums[index] = - abs(nums[index]) for i in range(len(nums)): if nums[i] > 0: res.append(i + 1) return res