LeetCode 422 Find All Duplicates in an Array

Keywords: Java Python

Main idea of the title:

Given a n array of integers, 1 < a [i] < n (n = the size of the array), some elements appear twice and others once.

Find all elements that appear twice in the array.

Algorithmic ideas:

Because all the stored integers are 1-n, we can use array subscripts to make repeated judgments to achieve time complexity O(N) and space complexity O(1).

Java implementation:

class Solution {
    public List<Integer> findDuplicates(int[] nums) {
        List<Integer> l = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            //Take the stored number as the subscript, find the corresponding position and multiply it by -1.
            //Unvisited locations must be positive numbers
            //The accessed location is a negative number, proving that the subscript + 1 duplication corresponding to this location
            if (nums[Math.abs(nums[i]) - 1] < 0)
                l.add(Math.abs(nums[i]));
            else
                nums[Math.abs(nums[i]) - 1] *= -1;
        }
        return l;
    }
}

Python 3 implementation:

class Solution:
    def findDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        res = []
        for x in nums:
            if nums[abs(x)-1] < 0:
                res.append(abs(x))
            else:
                nums[abs(x)-1] *= -1
        return res

My initial clumsy approach (short runtime):

class Solution {
    public List<Integer> findDuplicates(int[] nums) {
        List<Integer> l = new ArrayList<>();
        int j = 0;
        int i = 0;
        // Setting two pointers, i and j, initializes the stored number corresponding to the subscript of the array i
        // j jumps to the corresponding array subscript, sets the value to zero, and saves the initial value in j
        // j continues to jump until the pointed storage value is zero (proving that the value of j is repeated at this time), or coincides with the i pointer
        // i moves back to the location where the storage value is not zero, and assigns the storage value to j, J for a new round of jump
        // Until i traverses all array elements
        while (i < nums.length) {
            j = nums[i];
            nums[i] = -1;
            while (true) {
                if (nums[j - 1] == 0) {
                    l.add(j);
                    break;
                } else if (nums[j - 1] < 0) {
                    nums[j - 1] = 0;
                    break;
                } else {
                    int temp = nums[j - 1];
                    nums[j - 1] = 0;
                    j = temp;
                }
            }
            while (nums[i] <= 0) {
                i++;
                if (i == nums.length)
                    break;
            }
        }
        return l;
    }
}

Posted by phrygius on Sun, 10 Feb 2019 03:48:18 -0800