Number of Distinct Values II in O(n) Time and O(n) Space using C++


Given an array of integers, count how many distinct values exist in the array.

Example:

Input: [1, 5, -3, 1, -4, 2, -4, 7, 7]
Output: 6
Explanation: the distinct values in the array are [1, 5, -3, -4, 2, 7]

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 efficiently count the number of distinct values in an array. This is a common problem in data processing and analysis, where identifying unique elements is often required. A potential pitfall is using a naive approach that may not meet the time and space complexity requirements.

Approach

To solve this problem, we need to think about how to efficiently track unique elements. A naive solution might involve nested loops to compare each element with every other element, but this would result in O(n^2) time complexity, which is not optimal.

Instead, we can use a hash set to keep track of the elements we have seen so far. This allows us to check for duplicates and insert new elements in O(1) average time. By iterating through the array once and using a hash set, we can achieve the desired O(n) time complexity and O(n) space complexity.

Algorithm

Here is a step-by-step breakdown of the algorithm:

  1. Initialize an empty hash set.
  2. Iterate through each element in the array.
  3. For each element, check if it is already in the hash set.
  4. If it is not in the hash set, add it to the hash set.
  5. After iterating through the array, the size of the hash set will be the number of distinct values.

Code Implementation

#include <iostream>
#include <unordered_set>
#include <vector>

int countDistinctValues(const std::vector<int>& nums) {
    // Initialize an unordered set to store distinct values
    std::unordered_set<int> distinctValues;
    
    // Iterate through each element in the array
    for (int num : nums) {
        // Insert the element into the set
        distinctValues.insert(num);
    }
    
    // The size of the set is the number of distinct values
    return distinctValues.size();
}

int main() {
    // Example input
    std::vector<int> nums = {1, 5, -3, 1, -4, 2, -4, 7, 7};
    
    // Calculate and print the number of distinct values
    std::cout << "Number of distinct values: " << countDistinctValues(nums) << std::endl;
    
    return 0;
}

Complexity Analysis

The time complexity of this approach is O(n) because we iterate through the array once, and each insertion into the hash set takes O(1) on average. The space complexity is also O(n) because, in the worst case, all elements are distinct, and we store them in the hash set.

Edge Cases

Potential edge cases include:

Examples:

Input: []
Output: 0

Input: [1, 1, 1, 1]
Output: 1

Input: [-1, -1, 2, 2]
Output: 2

Testing

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

Using a testing framework like Google Test can help automate and manage these tests effectively.

Thinking and Problem-Solving Tips

When approaching such problems, consider the following tips:

Conclusion

In this blog post, we discussed how to count the number of distinct values in an array efficiently using a hash set. We covered the problem definition, approach, algorithm, code implementation, complexity analysis, edge cases, and testing. Understanding and solving such problems is crucial for improving algorithmic thinking and coding skills.

Additional Resources

For further reading and practice, consider the following resources: