Find Duplicates in Array in O(n) Time and O(n) Space using Java


Given an array of integers, return a new array containing only the duplicates.

The resulting array's values can be stored in any order.

Example:

Input: [2, 3, 1, 1, 4, 3, 2, 1]
Output: [2, 1, 3]
			

Note:

Your algorithm should run in O(n) time and use O(n) extra space.


Understanding the Problem

The core challenge of this problem is to identify all the duplicate elements in the array efficiently. This problem is significant in many real-world applications such as data cleaning, where identifying duplicates is crucial. A common pitfall is to use a nested loop to check for duplicates, which would result in an O(n^2) time complexity, making it inefficient for large datasets.

Approach

To solve this problem efficiently, we can use a HashMap to keep track of the frequency of each element in the array. This allows us to identify duplicates in O(n) time. Here’s a step-by-step approach:

  1. Initialize a HashMap to store the frequency of each element.
  2. Iterate through the array and update the frequency of each element in the HashMap.
  3. Iterate through the HashMap and collect elements that have a frequency greater than 1.
  4. Return the collected elements as the result.

Algorithm

Here is a detailed breakdown of the algorithm:

  1. Create a HashMap to store the frequency of each element.
  2. Traverse the array and for each element, increment its count in the HashMap.
  3. After processing the array, traverse the HashMap and collect all elements with a count greater than 1.
  4. Return the collected elements as the result.

Code Implementation

import java.util.*;

public class FindDuplicates {
    public static List<Integer> findDuplicates(int[] nums) {
        // HashMap to store the frequency of each element
        Map<Integer, Integer> frequencyMap = new HashMap<>();
        
        // List to store the result
        List<Integer> result = new ArrayList<>();
        
        // Traverse the array and update the frequency map
        for (int num : nums) {
            frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1);
        }
        
        // Collect elements with frequency greater than 1
        for (Map.Entry<Integer, Integer> entry : frequencyMap.entrySet()) {
            if (entry.getValue() > 1) {
                result.add(entry.getKey());
            }
        }
        
        return result;
    }

    public static void main(String[] args) {
        int[] nums = {2, 3, 1, 1, 4, 3, 2, 1};
        System.out.println(findDuplicates(nums)); // Output: [2, 1, 3]
    }
}

Complexity Analysis

The time complexity of this approach is O(n) because we traverse the array once to build the frequency map and then traverse the map to collect duplicates. The space complexity is also O(n) due to the additional space used by the HashMap.

Edge Cases

Consider the following edge cases:

Testing

To test the solution comprehensively, consider the following test cases:

Thinking and Problem-Solving Tips

When approaching such problems, it’s essential to think about the most efficient way to solve them. Using data structures like HashMaps can significantly reduce time complexity. Practice similar problems to improve your problem-solving skills and understand different algorithms and their applications.

Conclusion

In this blog post, we discussed how to find duplicates in an array efficiently using a HashMap. We covered the problem definition, approach, algorithm, code implementation, complexity analysis, edge cases, and testing. Understanding and solving such problems is crucial for improving your algorithmic thinking and coding skills.

Additional Resources

For further reading and practice, consider the following resources: