Facebook Pixel

2283. Check if Number Has Equal Digit Count and Digit Value

EasyHash TableStringCounting
Leetcode Link

Problem Description

You are given a string num that contains only digits. The string is 0-indexed with length n.

The problem asks you to check if the string satisfies a special property: for every position i in the string (where 0 <= i < n), the digit i should appear exactly num[i] times throughout the entire string.

In other words:

  • At position 0, if the character is '3', then the digit 0 should appear exactly 3 times in the entire string
  • At position 1, if the character is '2', then the digit 1 should appear exactly 2 times in the entire string
  • At position 2, if the character is '1', then the digit 2 should appear exactly 1 time in the entire string
  • And so on for each position...

Return true if this condition holds for every position in the string, otherwise return false.

For example, if num = "1210":

  • Position 0 has '1', so digit 0 should appear 1 time (it appears once at position 3) ✓
  • Position 1 has '2', so digit 1 should appear 2 times (it appears twice at positions 0 and 2) ✓
  • Position 2 has '1', so digit 2 should appear 1 time (it appears once at position 1) ✓
  • Position 3 has '0', so digit 3 should appear 0 times (it doesn't appear) ✓
  • All conditions are satisfied, so return true
Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The key insight is that we need to verify a relationship between positions and digit frequencies. Since we need to check if digit i appears exactly num[i] times in the string, we need two pieces of information:

  1. How many times each digit actually appears in the string
  2. What value is at each position

The natural approach is to first count all digit occurrences, then verify each position's requirement. We can think of this as a two-pass approach:

First pass: Count how many times each digit (0-9) appears in the entire string. This gives us the actual frequency of each digit.

Second pass: For each position i, check if the actual count of digit i matches the expected count num[i].

Why does this work? Because the problem essentially asks us to validate a "self-describing" property of the string. Each position describes how many times its index (as a digit) should appear. By pre-counting all frequencies, we can efficiently verify each position's claim in a single pass.

The solution uses Counter to quickly count digit frequencies, converting each character to an integer. Then it uses all() with a generator expression to check if every position satisfies its requirement: cnt[i] == int(x) where i is the position (which represents the digit we're checking) and x is the character at that position (which tells us the expected count).

This approach is efficient because we only need to traverse the string twice - once for counting and once for verification - giving us O(n) time complexity.

Solution Approach

The solution uses a counting and enumeration approach to verify the self-describing property of the string.

Step 1: Count digit frequencies

cnt = Counter(int(x) for x in num)

We use Python's Counter from the collections module to count how many times each digit appears in the string. The expression int(x) for x in num converts each character in the string to an integer (e.g., '3' becomes 3). The Counter creates a dictionary-like object where:

  • Keys are the digits that appear in the string
  • Values are their occurrence counts

For example, if num = "1210", then cnt would be {1: 2, 2: 1, 0: 1}, meaning digit 1 appears twice, digit 2 appears once, and digit 0 appears once.

Step 2: Verify each position's requirement

return all(cnt[i] == int(x) for i, x in enumerate(num))

We use enumerate(num) to iterate through each position i and its corresponding character x in the string. For each position:

  • i represents the digit we need to check (the position index)
  • int(x) represents the expected count (the value at that position)
  • cnt[i] gives us the actual count of digit i in the string

The all() function returns True only if every position satisfies the condition cnt[i] == int(x). If any position fails this check, it returns False.

Note that cnt[i] returns 0 if digit i doesn't exist in the counter, which correctly handles cases where a digit should appear 0 times.

Time Complexity: O(n) where n is the length of the string - we traverse the string twice (once for counting, once for verification).

Space Complexity: O(1) since we only store counts for at most 10 digits (0-9).

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through the solution with num = "2020":

Step 1: Count digit frequencies

  • First, we count how many times each digit appears in the string
  • Going through "2020": digit 2 appears twice, digit 0 appears twice
  • cnt = {2: 2, 0: 2}

Step 2: Verify each position's requirement Now we check if each position i has the correct value:

  • Position 0:

    • Character is '2', so digit 0 should appear 2 times
    • Check: cnt[0] == 2? → 2 == 2
  • Position 1:

    • Character is '0', so digit 1 should appear 0 times
    • Check: cnt[1] == 0? → 0 == 0 ✓ (cnt[1] returns 0 since digit 1 isn't in the counter)
  • Position 2:

    • Character is '2', so digit 2 should appear 2 times
    • Check: cnt[2] == 2? → 2 == 2
  • Position 3:

    • Character is '0', so digit 3 should appear 0 times
    • Check: cnt[3] == 0? → 0 == 0 ✓ (cnt[3] returns 0 since digit 3 isn't in the counter)

All positions satisfy their requirements, so the function returns true.

Another example with num = "1211":

Step 1: Count frequencies

  • cnt = {1: 2, 2: 2}

Step 2: Verify each position

  • Position 0: digit 0 should appear 1 time, but cnt[0] = 00 ≠ 1

Since position 0 fails the check, the function returns false immediately.

Solution Implementation

1from collections import Counter
2
3class Solution:
4    def digitCount(self, num: str) -> bool:
5        # Count the frequency of each digit in the string
6        # Convert each character to integer before counting
7        digit_frequency = Counter(int(digit) for digit in num)
8      
9        # Check if each position satisfies the condition:
10        # The digit at index i should equal the count of digit i in the entire string
11        # For all indices, verify that frequency of index value equals the digit at that position
12        return all(digit_frequency[index] == int(digit_at_index) 
13                   for index, digit_at_index in enumerate(num))
14
1class Solution {
2    public boolean digitCount(String num) {
3        // Array to store the frequency count of each digit (0-9)
4        int[] digitFrequency = new int[10];
5        int length = num.length();
6      
7        // Count the occurrence of each digit in the string
8        for (int i = 0; i < length; i++) {
9            int digit = num.charAt(i) - '0';
10            digitFrequency[digit]++;
11        }
12      
13        // Verify that each position i contains the count of digit i
14        // For example, if digit 0 appears 2 times, position 0 should contain '2'
15        for (int position = 0; position < length; position++) {
16            int expectedCount = num.charAt(position) - '0';
17            int actualCount = digitFrequency[position];
18          
19            if (expectedCount != actualCount) {
20                return false;
21            }
22        }
23      
24        return true;
25    }
26}
27
1class Solution {
2public:
3    bool digitCount(string num) {
4        // Array to store the frequency count of each digit (0-9)
5        int digitFrequency[10] = {0};
6      
7        // Count the occurrence of each digit in the string
8        for (char& currentChar : num) {
9            int digit = currentChar - '0';  // Convert character to integer
10            ++digitFrequency[digit];
11        }
12      
13        // Verify if each position i contains the count of digit i in the string
14        for (int i = 0; i < num.size(); ++i) {
15            int expectedCount = num[i] - '0';  // The value at position i
16            int actualCount = digitFrequency[i];  // Actual count of digit i
17          
18            if (actualCount != expectedCount) {
19                return false;
20            }
21        }
22      
23        return true;
24    }
25};
26
1/**
2 * Checks if a number string is self-describing.
3 * A string is self-describing if digit at index i represents the count of digit i in the string.
4 * 
5 * @param num - The input string containing only digits
6 * @returns true if the string is self-describing, false otherwise
7 */
8function digitCount(num: string): boolean {
9    // Initialize an array to count occurrences of each digit (0-9)
10    const digitFrequency: number[] = Array(10).fill(0);
11  
12    // Count the frequency of each digit in the input string
13    for (const char of num) {
14        // Convert character to number and increment its count
15        digitFrequency[Number(char)]++;
16    }
17  
18    // Verify if each position satisfies the self-describing property
19    for (let index = 0; index < num.length; index++) {
20        // Check if the count of digit 'index' matches the value at position 'index'
21        if (digitFrequency[index] !== Number(num[index])) {
22            return false;
23        }
24    }
25  
26    return true;
27}
28

Time and Space Complexity

The time complexity is O(n), where n is the length of the string num. This is because:

  • Creating the Counter iterates through all n characters once: O(n)
  • The all() function with the generator expression iterates through all n positions in the string once: O(n)
  • Total: O(n) + O(n) = O(n)

The space complexity is O(|Σ|), where |Σ| represents the size of the character set (the range of possible digit values), which is 10 for digits 0-9. This is because:

  • The Counter object stores at most 10 different digit counts (for digits 0 through 9), regardless of the input string length
  • Even though we iterate through n elements, the Counter can only have at most 10 keys
  • Therefore, the space used by the Counter is bounded by the constant 10, giving us O(10) = O(|Σ|)

Learn more about how to find time and space complexity quickly.

Common Pitfalls

Pitfall 1: Confusing Position Index with Digit Value

A frequent mistake is mixing up what needs to be counted versus what the expected count should be. Developers often incorrectly check if the digit at position i appears i times, rather than checking if digit i appears num[i] times.

Incorrect approach:

# WRONG: Checking if num[i] appears i times
return all(digit_frequency[int(num[i])] == i for i in range(len(num)))

Correct approach:

# RIGHT: Checking if digit i appears num[i] times
return all(digit_frequency[i] == int(num[i]) for i in range(len(num)))

Pitfall 2: Not Handling Digits Beyond String Length

When the string length is less than 10, some digits (those greater than or equal to the string length) cannot have position indices in the string. If any of these digits appear in the string, the condition is automatically violated since there's no position to specify their count.

Example: If num = "302" (length 3), digit 3 appears once but there's no position 3 to specify that it should appear once. This string should return false.

Solution: The provided code handles this correctly because when we enumerate through positions 0 to n-1, we only check digits that have corresponding positions. However, to be explicit about this edge case:

def digitCount(self, num: str) -> bool:
    digit_frequency = Counter(int(digit) for digit in num)
  
    # First check: any digit >= len(num) should not appear
    for digit in digit_frequency:
        if digit >= len(num) and digit_frequency[digit] > 0:
            return False
  
    # Then check the main condition
    return all(digit_frequency[i] == int(num[i]) for i in range(len(num)))

Pitfall 3: Forgetting Zero-Count Requirements

When num[i] = '0', it means digit i should not appear anywhere in the string. Developers sometimes forget to verify this "absence" requirement.

Solution: The Counter object in Python handles this elegantly - accessing a non-existent key returns 0, which correctly validates the zero-count requirement. Just ensure you're comparing with the integer value, not the character:

# Correct: converts '0' to 0 for comparison
digit_frequency[i] == int(num[i])  

# Wrong: comparing with character '0'
digit_frequency[i] == num[i]
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

What are the two properties the problem needs to have for dynamic programming to be applicable? (Select 2)


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More