Hash in place of Leetcode array

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

Posted by g_p_java on Thu, 18 Jun 2020 21:38:56 -0700