How to count each digit in a range of integers?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Counting how many times each digit appears in a range can be done by brute force, but that becomes slow for large intervals. A better approach uses positional counting: analyze the ones place, tens place, hundreds place, and so on, then combine those counts mathematically.
Brute force is correct but not scalable
The simple solution is:
- loop from
atob - convert each number to digits
- update counters for
0through9
Example:
This is fine for small ranges, but it costs roughly O((b - a + 1) * digits) operations. For very large ranges, you want something closer to O(log b).
Count digits from 0 to n position by position
The standard optimization counts how often each digit appears at each decimal position. For a position value factor = 1, 10, 100, ..., split n into:
- '
higher = n // (factor * 10)' - '
current = (n // factor) % 10' - '
lower = n % factor'
Those three parts tell you how many full cycles and partial cycles the current digit position has completed.
A clean implementation for counting digit appearances from 0 to n can be written like this:
The counts[0] -= factor adjustment handles the fact that leading zeros should not be counted as visible digits.
Convert 0..n counting into range counting
Once you can count digits from 0 to n, a general inclusive range a..b is just:
Now:
returns the counts for all digits in that interval without iterating over every number one by one.
Why the positional method works
At each position, digits repeat in regular cycles.
For the ones place:
- every block of 10 numbers contains each digit once
For the tens place:
- every block of 100 numbers contains each digit in that position for 10 consecutive values
For the hundreds place:
- every block of 1000 numbers contains each digit in that position for 100 consecutive values
The algorithm exploits those cycles instead of enumerating every number.
Common Pitfalls
The biggest mistake is mishandling zeros. Leading zeros are not part of the written representation of ordinary integers, so they need special correction in the positional formula.
Another mistake is forgetting that range counting should usually be inclusive. If the task says "from a to b," make sure both endpoints are handled consistently.
Developers also assume brute force is good enough until the input becomes huge. For interview-style or algorithmic versions of this problem, the positional method is usually what is expected.
Finally, be careful when the range includes negative numbers. The standard digit-counting formulas are usually defined for non-negative integer representations.
Summary
- Brute force counting is easy to write but too slow for large ranges.
- The efficient solution counts digit contributions position by position.
- A helper for
0..ncan be turned into range counting by subtraction. - Zero needs special handling because leading zeros should not be counted.
- Positional analysis reduces the problem from scanning every number to analyzing decimal cycles.
Related reading
- How to count groups of same cells in a 2d array?
- How to count integers between large A and B with a certain property?
- How to count Multiply-Adds operations?
- How to count string num with limit memory?
- How to count possible combination for coin problem
- How to create the most compact mapping n → isprimen up to a limit N?
- How to count the frequency of the elements in an unordered list?
- How to create a distributed system that performs a task and come to a consensus of result?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.