title: Check if Number Has Equal Digit Count and Digit Value slug: check-if-number-has-equal-digit-count-and-digit-value difficulty: easy leetcode_id: 2283 leetcode_url: https://leetcode.com/problems/check-if-number-has-equal-digit-count-and-digit-value/ categories: - strings - hash-tables patterns: - prefix-sum function_signature: "def digit_count(num: str) -> bool:" test_cases: visible: - input: { num: "1210" } expected: true - input: { num: "030" } expected: false hidden: - input: { num: "2020" } expected: true - input: { num: "0" } expected: false - input: { num: "10" } expected: false - input: { num: "21200" } expected: true - input: { num: "1111" } expected: false - input: { num: "2100" } expected: true description: | You are given a **0-indexed** string `num` of length `n` consisting of digits. Return `true` *if for **every** index* `i` *in the range* `0 <= i < n`*, the digit* `i` *occurs* `num[i]` *times in* `num`*, otherwise return* `false`. constraints: | - `n == num.length` - `1 <= n <= 10` - `num` consists only of digits examples: - input: 'num = "1210"' output: "true" explanation: | num[0] = '1'. The digit 0 occurs once in num. num[1] = '2'. The digit 1 occurs twice in num. num[2] = '1'. The digit 2 occurs once in num. num[3] = '0'. The digit 3 occurs zero times in num. The condition holds true for every index in "1210", so return true. - input: 'num = "030"' output: "false" explanation: | num[0] = '0'. The digit 0 should occur zero times, but actually occurs twice in num. num[1] = '3'. The digit 1 should occur three times, but actually occurs zero times in num. num[2] = '0'. The digit 2 occurs zero times in num. The indices 0 and 1 both violate the condition, so return false. explanation: intuition: | Think of this problem as a **self-describing number** puzzle. Each position in the string tells you how many times that position's index should appear as a digit elsewhere in the string. Imagine the string as a set of rules: position 0 says "the digit 0 must appear exactly `num[0]` times", position 1 says "the digit 1 must appear exactly `num[1]` times", and so on. Your job is to verify that the string follows its own rules. The key insight is that we need to **count the occurrences** of each digit first, then check if each position's value matches the count for its corresponding index. This is a classic counting problem where we build a frequency map and then validate against it. approach: | We solve this using a **Counting Approach**: **Step 1: Count digit frequencies** - Create a frequency array or hash map to count how many times each digit (0-9) appears in the string - Iterate through the string once to populate these counts   **Step 2: Validate the self-describing property** - For each index `i` from `0` to `n-1`: - Get the expected count from `num[i]` (convert character to integer) - Get the actual count of digit `i` from our frequency map - If they don't match, return `false`   **Step 3: Return the result** - If all positions pass validation, return `true`   This approach works because we separate the problem into two clear phases: counting and validating. The counting phase gives us the ground truth, and the validation phase checks if the string's claims match reality. common_pitfalls: - title: Confusing Index and Value description: | The problem has a subtle twist: at index `i`, the *value* `num[i]` tells us how many times the *digit* `i` should appear. For example, at index 2, if `num[2] = '1'`, this means the digit `2` should appear exactly once in the string — not that the digit `1` should appear twice. Read carefully: we're checking if digit `i` occurs `num[i]` times. wrong_approach: "Checking if digit num[i] occurs i times" correct_approach: "Checking if digit i occurs num[i] times" - title: Character vs Integer Conversion description: | Remember that `num` is a string, so `num[i]` gives a character like `'2'`, not the integer `2`. You need to convert: `int(num[i])` in Python, or `num[i] - '0'` in languages like C++ or Java. Forgetting this conversion leads to comparing characters with integers, which will give wrong results or type errors. wrong_approach: "Comparing num[i] directly with count" correct_approach: "Convert num[i] to integer before comparison" - title: Not Handling All Indices description: | Since the string has length `n`, we only need to check indices `0` through `n-1`. We only care about digits `0` through `n-1` as well, since larger digits can't be valid indices. However, digits larger than `n-1` appearing in the string is fine — they just won't be checked as indices. The constraint `n <= 10` ensures all digits 0-9 are potentially valid. key_takeaways: - "**Self-describing structures**: Some problems define constraints that reference themselves — break these into counting and validation phases" - "**Frequency counting pattern**: Building a frequency map first simplifies many validation problems" - "**Index vs value awareness**: Pay close attention to what the index represents vs what the value represents" - "**Small constraint optimisation**: With `n <= 10`, even O(n^2) would work, but O(n) is cleaner and teaches better habits" time_complexity: "O(n). We iterate through the string twice: once to count frequencies, once to validate." space_complexity: "O(1). We use a fixed-size frequency array of 10 elements (for digits 0-9), regardless of input size." solutions: - approach_name: Frequency Counting is_optimal: true code: | def digit_count(num: str) -> bool: # Count occurrences of each digit (0-9) freq = [0] * 10 for char in num: freq[int(char)] += 1 # Check if each index i has digit i appearing num[i] times for i in range(len(num)): expected = int(num[i]) # How many times digit i should appear actual = freq[i] # How many times digit i actually appears if expected != actual: return False return True explanation: | **Time Complexity:** O(n) — Two passes through the string of length n. **Space Complexity:** O(1) — Fixed array of 10 integers. We first count all digit occurrences, then verify each position's claim. The fixed-size frequency array makes this space-efficient. - approach_name: Counter with Pythonic Check is_optimal: true code: | from collections import Counter def digit_count(num: str) -> bool: # Count all digit occurrences count = Counter(num) # Check each index: digit i should occur num[i] times for i, char in enumerate(num): expected = int(char) actual = count.get(str(i), 0) # Get count of digit i (as string) if expected != actual: return False return True explanation: | **Time Complexity:** O(n) — Counter creation and validation loop. **Space Complexity:** O(k) — Where k is the number of unique digits (at most 10). This approach uses Python's Counter for cleaner counting. Note that we look up `str(i)` since Counter keys are characters, not integers. - approach_name: One-Liner (Pythonic) is_optimal: true code: | from collections import Counter def digit_count(num: str) -> bool: count = Counter(num) return all(count.get(str(i), 0) == int(c) for i, c in enumerate(num)) explanation: | **Time Complexity:** O(n) — Single pass with generator expression. **Space Complexity:** O(k) — Counter storage for unique digits. A concise one-liner using `all()` with a generator. For each position, we check if the count of that index-as-digit matches the expected value. Elegant but less readable for beginners.