Find the Number of Distinct Colors Among the Balls

Updated on 28 May, 2025
Find the Number of Distinct Colors Among the Balls header image

Problem Statement

In the given scenario, you are presented with an integer limit and a two-dimensional array queries, each sub-array containing two integers. The range from 0 to limit represents distinct labels for limit + 1 balls, which initially are not colored. Upon executing each query [x, y] from the queries array, a ball at position (or label) x is colored with the value y. Your task is to track changes after each query and document the number of distinct colors currently present among all the balls.

Thus, you need to output an array result, where each entry result[i] shows the count of unique colors after processing the i-th query. It's essential to understand that any ball which has not been colored yet is not considered in color counting.

Examples

Example 1

Input:

limit = 4, queries = [[1,4],[2,5],[1,3],[3,4]]

Output:

[1,2,2,3]

Explanation:

* After query 0, ball 1 has color 4.
* After query 1, ball 1 has color 4, and ball 2 has color 5.
* After query 2, ball 1 has color 3, and ball 2 has color 5.
* After query 3, ball 1 has color 3, ball 2 has color 5, and ball 3 has color 4.

Example 2

Input:

limit = 4, queries = [[0,1],[1,2],[2,2],[3,4],[4,5]]

Output:

[1,2,2,3,4]

Explanation:

* After query 0, ball 0 has color 1.
* After query 1, ball 0 has color 1, and ball 1 has color 2.
* After query 2, ball 0 has color 1, and balls 1 and 2 have color 2.
* After query 3, ball 0 has color 1, balls 1 and 2 have color 2, and ball 3 has color 4.
* After query 4, ball 0 has color 1, balls 1 and 2 have color 2, ball 3 has color 4, and ball 4 has color 5.

Constraints

  • 1 <= limit <= 10^9
  • 1 <= n == queries.length <= 10^5
  • queries[i].length == 2
  • 0 <= queries[i][0] <= limit
  • 1 <= queries[i][1] <= 10^9

Approach and Intuition

To solve the problem effectively, consider the following approach:

  1. Use Dictionary for Color Tracking:

    • Maintain a dictionary ball_to_color to map each ball label to its current color.
  2. Track Color Frequencies:

    • Use another dictionary color_count to store how many balls are using each color.
  3. Process Each Query:

    • For each query [x, y]:

      • If ball x is already colored:

        • Decrease the count of its current color in color_count.
        • If the count becomes zero, that color is no longer in use.
      • Assign color y to ball x.

      • Increase the count of color y in color_count.

  4. Count Active Colors:

    • The number of active colors at each step is the number of keys in color_count with non-zero values.
    • Track and append this value to the result array after each query.
  5. Efficiency:

    • All operations on dictionaries (lookup, insert, update) are O(1) on average, allowing the algorithm to scale comfortably within the given constraints.

This method ensures that color assignment, tracking, and counting are handled efficiently using hash maps, providing optimal performance even for high volumes of queries and large ball label ranges.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    vector<int> processQueries(int maxLimit, vector<vector<int>>& inputQueries) {
        int queryCount = inputQueries.size();
        vector<int> outputs(queryCount);
        unordered_map<int, int> colorFrequency, ballToColor;

        for (int index = 0; index < queryCount; index++) {
            int currentBall = inputQueries[index][0], newColor = inputQueries[index][1];

            if (ballToColor.find(currentBall) != ballToColor.end()) {
                int oldColor = ballToColor[currentBall];
                colorFrequency[oldColor]--;

                if (colorFrequency[oldColor] == 0) colorFrequency.erase(oldColor);
            }
            ballToColor[currentBall] = newColor;
            colorFrequency[newColor]++;
            outputs[index] = colorFrequency.size();
        }

        return outputs;
    }
};
  • Implement a function to track and return the number of distinct colors used to paint a series of balls given a set of operations.
  • Use C++ with an unordered_map for efficient lookup and update of color frequencies and mappings from balls to their colors.
  • Cycle through each query, which contains the ball number and new color.
  • Check if the ball is already painted:
    • If yes, decrease the frequency count of its current color.
    • Remove the color from the frequency tracking if its count reduces to zero.
  • Update the ball’s color in the mapping and increment the new color's frequency.
  • Store the count of distinct colors after processing each query.
  • Return the results as a vector, where each element corresponds to the distinct colors count after each query.
java
class Solution {

    public int[] processQueries(int max, int[][] inquiry) {
        int count = inquiry.length;
        int[] outcomes = new int[count];
        Map<Integer, Integer> hueMap = new HashMap<>();
        Map<Integer, Integer> sphereMap = new HashMap<>();

        for (int idx = 0; idx < count; idx++) {
            int sphere = inquiry[idx][0];
            int hue = inquiry[idx][1];

            if (sphereMap.containsKey(sphere)) {
                int oldHue = sphereMap.get(sphere);
                hueMap.put(oldHue, hueMap.get(oldHue) - 1);

                if (hueMap.get(oldHue) == 0) {
                    hueMap.remove(oldHue);
                }
            }
            sphereMap.put(sphere, hue);

            hueMap.put(hue, hueMap.getOrDefault(hue, 0) + 1);

            outcomes[idx] = hueMap.size();
        }
        return outcomes;
    }
}

The provided Java solution defines a method processQueries that determines the number of distinct colors present in a list of inquiries about colored balls. Each inquiry contains information about a ball (represented by sphere) and its color (represented by hue). The main focus is on finding the count of unique hues for each inquiry and updating this count dynamically as inquiries progress.

Here's how this solution operates:

  • Two hash maps, hueMap and sphereMap, are initialized to track the count of each hue and the current hue for each sphere, respectively.
  • Loop through each inquiry:
    • If the sphere already has an assigned hue, update hueMap by decreasing the count of the old hue. If this count reaches zero, remove the old hue from hueMap.
    • Update or add the current inquiry's hue in the sphereMap.
    • Adjust hueMap to include or update the count of the new hue.
    • Record the count of distinct hues present (hueMap.size()) in the result for that particular inquiry.
  • The outcome for each inquiry (i.e., the count of distinct hues after considering each inquiry) is stored in the outcomes array, which the method returns.

This approach effectively maps spheres to their hues while maintaining a real-time count of unique hues. Each entry in the results array corresponds to the number of distinct hues noted after processing each inquiry up to that point. The use of hash maps allows for quick updates and lookups, making this method efficient for handling a potentially large number of inquiries.

python
class Solution:
    def getColorDistribution(self, max_count: int, colorSeq: List[List[int]]) -> List[int]:
        query_count = len(colorSeq)
        output = []
        ball_color_map = {}
        color_frequency = {}

        for index in range(query_count):
            ball_id, color_id = colorSeq[index]

            if ball_id in ball_color_map:
                old_color = ball_color_map[ball_id]
                color_frequency[old_color] -= 1

                if color_frequency[old_color] == 0:
                    del color_frequency[old_color]

            ball_color_map[ball_id] = color_id
            color_frequency[color_id] = color_frequency.get(color_id, 0) + 1

            output.append(len(color_frequency))

        return output

This Python solution addresses the problem of finding the number of distinct colors among balls based on sequential ball-color updates. The getColorDistribution function inside the Solution class takes two parameters: max_count, which is not used in the function, and colorSeq, a list where each element is another list containing a ball_id and a color_id.

Here’s a step-by-step breakdown of what this function does:

  1. Initialize an empty list named output to store the results.
  2. Use two dictionaries, ball_color_map to map each ball to its current color, and color_frequency to count how many balls there are of each color.
  3. Iterate through the colorSeq.
    • Extract the ball_id and color_id from each entry.
    • Check if the ball already has a mapped color:
      • If it does, decrease the count of the old color in color_frequency.
      • If this decremented count reaches zero, remove the old color from color_frequency.
    • Map the ball_id to the new color_id and update or add the new color's frequency in color_frequency.
    • Append the number of unique colors, which is the length of color_frequency, to the output list.
  4. Return the output list, which represents the number of distinct colors among the balls at each sequential update.

In conclusion, this function effectively tracks and counts the number of distinct colors by utilizing dictionary operations to handle and update mappings and counts efficiently.

Comments

No comments yet.