AlgoMaster Logo

Number of Digit One

hardFrequency8 min readUpdated June 23, 2026

Understanding the Problem

We count every individual occurrence of the digit 1 across all numbers from 0 to n, not how many numbers contain a 1. The number 11 contributes 2, the number 111 contributes 3, and so on.

A brute force approach iterates through every number from 1 to n and counts the 1s in each. With n up to 10^9, that means examining the digits of up to a billion numbers, which is too slow.

A faster approach analyzes each digit position independently. Instead of asking "how many 1s are in number k?", we ask "how many times does digit 1 appear in the ones place across all numbers from 0 to n? In the tens place? In the hundreds place?" This position-by-position counting leads to an O(log n) solution.

Key Constraints:

  • 0 <= n <= 10^9 → With n up to a billion, iterating through every number is too slow. Even O(n) is around 10^9 operations. We need O(log n).
  • n can be 0 → an edge case where the answer is 0.

Approach 1: Brute Force

Intuition

Iterate through every number from 1 to n, break each one into its digits, and count how many of those digits are 1. For each number, we extract digits using modulo and division, checking whether each digit equals 1. This is correct but too slow for the given constraints.

Algorithm

  1. Initialize count = 0.
  2. For each number i from 1 to n:
    • While i > 0, check if i % 10 == 1. If so, increment count.
    • Divide i by 10 to move to the next digit.
  3. Return count.

Example Walkthrough

1Start: count=0, check each number for digit 1s
0
1
i
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
10
10
11
11
12
12
13
1/6

Code

With n up to 10^9, this brute force is too slow. The digit 1 appears in a repeating pattern at each position, so the next approach calculates the count at each position directly from the digits of n.

Approach 2: Digit-by-Digit Mathematical Counting (Optimal)

Intuition

Instead of scanning every number, we analyze each digit position independently and calculate how many times the digit 1 occupies that position across all numbers from 0 to n.

We decompose n relative to each digit position into three parts: the higher part (digits to the left), the current digit, and the lower part (digits to the right). The place value is the factor (1, 10, 100, ...).

The tens digit cycles through 0-9 repeatedly. For each full cycle controlled by the higher part, the digit 1 appears exactly factor times. This gives us three cases:

  • Current digit = 0: Only complete cycles contribute. Count = higher * factor.
  • Current digit = 1: Complete cycles plus a partial cycle. Count = higher * factor + lower + 1.
  • Current digit >= 2: Complete cycles plus one full extra cycle. Count = (higher + 1) * factor.

We repeat this for every digit position and sum up.

Algorithm

  1. Initialize count = 0 and factor = 1 (starting from the ones place).
  2. While factor <= n:
    • Compute higher = n / (factor * 10) (digits to the left).
    • Compute current = (n / factor) % 10 (the digit at this position).
    • Compute lower = n % factor (digits to the right).
    • If current == 0: add higher * factor to count.
    • If current == 1: add higher * factor + lower + 1 to count.
    • If current >= 2: add (higher + 1) * factor to count.
    • Multiply factor by 10 to move to the next position.
  3. Return count.

Example Walkthrough

1n=3141, analyze each digit position. Start from ones place (rightmost).
3
1
4
1
factor=1
1/6

Code

The mathematical approach is already optimal at O(log n). The next approach reaches the same time complexity with a more general framework, digit dynamic programming, which extends to variations like counting numbers with exactly k ones or other per-digit constraints.

Approach 3: Recursive Digit DP

Intuition

Digit dynamic programming builds every number from 0 to n digit by digit, from the most significant position to the least. At each step it tracks one bit of state: whether we are still "tight" (the digits placed so far match the prefix of n exactly, so the next digit is capped by n) or "free" (we already placed a digit smaller than n's at some earlier position, so every remaining digit can range over 0-9).

At each position we place digits 0 through the limit (the digit of n if tight, 9 otherwise). When we place a 1, we count how many complete numbers include this particular 1. If we become free, the remaining positions can each be 0-9, so this 1 appears in 10^(remaining positions) numbers. If we stay tight, the remaining positions are bounded by the rest of n, so this 1 appears in lower + 1 numbers.

For this specific problem the closed-form formula from Approach 2 is shorter and faster. Digit DP generalizes to problems with extra per-digit constraints, where no simple formula exists.

Algorithm

  1. Convert n to an array of digits.
  2. Define a recursive function dp(position, tight) that returns the total count of 1s from this position onward across all valid numbers.
  3. At each position, try placing digits 0 through the limit (digit of n if tight, 9 otherwise).
  4. When placing digit 1:
    • If not tight afterward, this 1 appears in 10^(remaining positions) numbers.
    • If still tight, compute how many valid numbers remain by looking at the remaining digits of n.
  5. Recursively add the 1s contributed by future positions.
  6. Memoize on (position, tight) to avoid redundant computation.

Example Walkthrough

1Start: pos=0, tight=true. Can place digits 0..3 at position 0.
0
3
pos=0
1
1
2
4
3
1
1/6

Code