Digit-Based Number Problems
Solve one Java logic problem at a time, then flip for the complete explanation and program.
Solve one Java logic problem at a time, then flip for the complete explanation and program.
Java Logic Development · Chapter 02 Companion Article
Fifteen digit-manipulation problems built around one repeating pattern — number % 10 extracts the last digit and number / 10 removes it. Counting, summing, reversing, extracting, and replacing digits all reuse this same extract-process-remove loop.
Digit-based number problems teach an important programming pattern: repeatedly extract and process individual digits of an integer. These problems strengthen loop logic, arithmetic operators, condition handling, and number manipulation without depending on strings or collections.
Most digit problems are built around two operations: number % 10 extracts the last digit, and number / 10 removes the last digit using integer division. For example, with number = 5837:
| Operation | Result |
|---|---|
5837 % 10 | 7 |
5837 / 10 | 583 |
583 % 10 | 3 |
583 / 10 | 58 |
This extract-process-remove pattern is the foundation of most problems in this chapter.
Digit counting determines how many decimal digits are present in an integer. Examples: 5837 → 4, 91 → 2, 7 → 1, 0 → 1. The usual arithmetic approach repeatedly divides the number by 10 until nothing remains.
For every loop iteration:
/ 10.public class CountDigits {
public static void main(String[] args) {
int number = 58372;
int temp = Math.abs(number);
int count = 0;
if (temp == 0) {
count = 1;
} else {
while (temp > 0) {
count++;
temp /= 10;
}
}
System.out.println("Number of digits: " + count);
}
}
Number of digits: 5
For 58372:
| temp | count |
|---|---|
| 58372 | 0 |
| 5837 | 1 |
| 583 | 2 |
| 58 | 3 |
| 5 | 4 |
| 0 | 5 |
The loop executes once for each digit.
Integer division by 10 removes one decimal digit from the right side. Therefore, counting how many divisions are required to reach 0 gives the number of digits.
A normal while (number > 0) loop never executes for 0, but zero contains one digit. Handle it separately.
The minus sign is not a digit. Use Math.abs() before counting.
int count = String.valueOf(Math.abs(number)).length(); is shorter but does not demonstrate digit-processing logic.
O(d)O(1)Here d is the number of digits.
For logic-development questions, interviewers usually expect the arithmetic / 10 approach rather than converting the number to a string.
The sum of digits is obtained by extracting each digit and adding it to an accumulator. Example: 5832 → 5 + 8 + 3 + 2 = 18.
digit = number % 10
sum += digit
number /= 10
public class SumOfDigits {
public static void main(String[] args) {
int number = 5832;
int temp = Math.abs(number);
int sum = 0;
while (temp > 0) {
int digit = temp % 10;
sum += digit;
temp /= 10;
}
System.out.println("Sum of digits: " + sum);
}
}
Sum of digits: 18
| temp | digit | sum |
|---|---|---|
| 5832 | 2 | 2 |
| 583 | 3 | 5 |
| 58 | 8 | 13 |
| 5 | 5 | 18 |
The remainder after division by 10 always represents the current last decimal digit. Processing every last digit eventually covers the complete number.
Digit sums appear in:
O(d)O(1)Writing sum = digit; instead of sum += digit; — the first statement replaces the previous result rather than accumulating it.
Instead of adding digits, multiply them together. Example: 234 → 2 × 3 × 4 = 24.
The accumulator must start with 1. Correct: int product = 1;. Incorrect: int product = 0; — any value multiplied by zero remains zero.
public class ProductOfDigits {
public static void main(String[] args) {
int number = 234;
int temp = Math.abs(number);
int product = temp == 0 ? 0 : 1;
while (temp > 0) {
int digit = temp % 10;
product *= digit;
temp /= 10;
}
System.out.println("Product of digits: " + product);
}
}
Product of digits: 24
| temp | digit | product |
|---|---|---|
| 234 | 4 | 4 |
| 23 | 3 | 12 |
| 2 | 2 | 24 |
For 205, the product becomes 2 × 0 × 5 = 0. Once a zero digit is encountered, the final product must be zero.
O(d)O(1)Pay attention to accumulator initialization. Sum problems normally begin with 0, while product problems normally begin with 1.
Reversing a number places its digits in opposite order. Example: 12345 → 54321. The standard formula is reverse = reverse * 10 + digit.
public class ReverseNumber {
public static void main(String[] args) {
int number = 12345;
int temp = Math.abs(number);
int reverse = 0;
while (temp > 0) {
int digit = temp % 10;
reverse = reverse * 10 + digit;
temp /= 10;
}
if (number < 0) {
reverse = -reverse;
}
System.out.println("Reversed number: " + reverse);
}
}
Reversed number: 54321
| temp | digit | reverse |
|---|---|---|
| 12345 | 5 | 5 |
| 1234 | 4 | 54 |
| 123 | 3 | 543 |
| 12 | 2 | 5432 |
| 1 | 1 | 54321 |
Suppose the current reverse is 54 and the next digit is 3:
54 * 10 = 540
540 + 3 = 543
Multiplication by 10 creates space for the new last digit.
1200 becomes 21, not 0021. An integer cannot preserve leading zeros.
A reversed value can exceed the int range even when the original value is valid. For production-quality code, use long or perform an overflow check before reverse * 10 + digit.
O(d)O(1)Using reverse += digit; — this only adds digits and does not construct the reversed number.
The first digit is the leftmost digit. Example: 58374 → 5. Unlike the last digit, there is no direct % 10 operation for the first digit.
Repeatedly divide by 10 until only one digit remains.
public class FirstDigit {
public static void main(String[] args) {
int number = 58374;
int temp = Math.abs(number);
while (temp >= 10) {
temp /= 10;
}
System.out.println("First digit: " + temp);
}
}
First digit: 5
58374
5837
583
58
5
When the value becomes smaller than 10, only its first digit remains.
For a positive number: firstDigit = number / 10^(digits - 1). The repeated-division solution is usually simpler and easier to reason about.
O(d)O(1)The last digit is the rightmost decimal digit. The modulo operator makes this one of the simplest digit problems.
lastDigit = number % 10
public class LastDigit {
public static void main(String[] args) {
int number = 58374;
int lastDigit = Math.abs(number % 10);
System.out.println("Last digit: " + lastDigit);
}
}
Last digit: 4
Any integer can be written as number = quotient * 10 + remainder. The remainder must be between 0 and 9, which is exactly the last digit.
| Number | Last Digit |
|---|---|
| 58374 | 4 |
| 100 | 0 |
| 7 | 7 |
O(1)O(1)This problem combines two earlier operations: extract the last digit using % 10, and find the first digit using repeated division. Example: for 58374, first digit = 5, last digit = 4, sum = 9.
public class SumFirstLastDigit {
public static void main(String[] args) {
int number = 58374;
int temp = Math.abs(number);
int lastDigit = temp % 10;
while (temp >= 10) {
temp /= 10;
}
int firstDigit = temp;
int sum = firstDigit + lastDigit;
System.out.println("First digit: " + firstDigit);
System.out.println("Last digit: " + lastDigit);
System.out.println("Sum: " + sum);
}
}
First digit: 5
Last digit: 4
Sum: 9
For 7: first digit = 7, last digit = 7, sum = 14. Whether this is expected depends on the problem definition.
O(d)O(1)Clarify the expected behavior for single-digit input before writing the solution if the specification is ambiguous.
Scan every digit while maintaining the largest value encountered so far. Digits can only range from 0 to 9.
public class LargestDigit {
public static void main(String[] args) {
int number = 583274;
int temp = Math.abs(number);
int largest = 0;
while (temp > 0) {
int digit = temp % 10;
if (digit > largest) {
largest = digit;
}
temp /= 10;
}
System.out.println("Largest digit: " + largest);
}
}
Largest digit: 8
Digits are processed as 4, 7, 2, 3, 8, 5:
| digit | largest |
|---|---|
| 4 | 4 |
| 7 | 7 |
| 2 | 7 |
| 3 | 7 |
| 8 | 8 |
| 5 | 8 |
If the largest digit becomes 9, scanning can stop because no decimal digit can exceed 9.
if (largest == 9) {
break;
}
O(d)O(1)Comparing the complete remaining number instead of the extracted digit. Correct: if (digit > largest)
Track the minimum digit encountered while scanning the number. Since decimal digits range from 0 to 9, initialize the minimum to 9.
public class SmallestDigit {
public static void main(String[] args) {
int number = 583274;
int temp = Math.abs(number);
int smallest = temp == 0 ? 0 : 9;
while (temp > 0) {
int digit = temp % 10;
if (digit < smallest) {
smallest = digit;
}
temp /= 10;
}
System.out.println("Smallest digit: " + smallest);
}
}
Smallest digit: 2
Every decimal digit is less than or equal to 9, making it a safe starting maximum. Initializing with 0 would fail for positive numbers because no digit can be smaller than zero.
If 0 is found, no smaller decimal digit exists:
if (smallest == 0) {
break;
}
O(d)O(1)A digit is even when digit % 2 == 0. The even decimal digits are 0, 2, 4, 6, 8.
public class CountEvenDigits {
public static void main(String[] args) {
int number = 583264;
int temp = Math.abs(number);
int count = 0;
if (temp == 0) {
count = 1;
} else {
while (temp > 0) {
int digit = temp % 10;
if (digit % 2 == 0) {
count++;
}
temp /= 10;
}
}
System.out.println("Even digits: " + count);
}
}
Even digits: 3
Digits: 5, 8, 3, 2, 6, 4. Even digits: 8, 2, 6, 4. Actually, there are 4 even digits. Therefore, the correct output for the program is:
Even digits: 4
This type of manual verification is important when testing digit problems.
The number 0 itself contains one even digit because 0 % 2 == 0.
O(d)O(1)A digit is odd when digit % 2 != 0. Odd decimal digits are 1, 3, 5, 7, 9.
public class CountOddDigits {
public static void main(String[] args) {
int number = 583264;
int temp = Math.abs(number);
int count = 0;
while (temp > 0) {
int digit = temp % 10;
if (digit % 2 != 0) {
count++;
}
temp /= 10;
}
System.out.println("Odd digits: " + count);
}
}
Odd digits: 2
Digits: 4, 6, 2, 3, 8, 5. Odd digits: 3, 5. Count = 2.
For normal positive integers: evenDigitCount + oddDigitCount = totalDigitCount. This is useful for validating a solution.
O(d)O(1)Digit frequency tells how many times each digit from 0 through 9 occurs. Example: 1223052 → 0:1, 1:1, 2:3, 3:1, 5:1.
Because there are exactly ten decimal digits, use int[] frequency = new int[10];. The array index represents the digit — frequency[5] stores the number of occurrences of digit 5.
public class DigitFrequency {
public static void main(String[] args) {
int number = 1223052;
int temp = Math.abs(number);
int[] frequency = new int[10];
if (temp == 0) {
frequency[0] = 1;
} else {
while (temp > 0) {
int digit = temp % 10;
frequency[digit]++;
temp /= 10;
}
}
for (int digit = 0; digit <= 9; digit++) {
if (frequency[digit] > 0) {
System.out.println(digit + " -> " + frequency[digit]);
}
}
}
}
0 -> 1
1 -> 1
2 -> 3
3 -> 1
5 -> 1
The possible values are known in advance: 0 through 9. An array therefore gives:
O(d)O(1)Although an array is used, its size is always exactly 10, so auxiliary space remains constant.
Common variations include:
Integer division by 10 removes the final decimal digit. Example: 5837 / 10 = 583.
public class RemoveLastDigit {
public static void main(String[] args) {
int number = 5837;
int result = number / 10;
System.out.println("After removing last digit: " + result);
}
}
After removing last digit: 583
| Number | After / 10 |
|---|---|
| 5837 | 583 |
| 120 | 12 |
| 45 | 4 |
| 7 | 0 |
Java integer division discards the fractional part. Mathematically 5837 / 10 = 583.7, but integer arithmetic stores 583 — the final digit disappears.
Java truncates integer division toward zero. Example: -5837 / 10 = -583.
O(1)O(1)A number can be decomposed into individual decimal digits using % 10 and / 10. There are two common requirements:
public class ExtractDigitsReverseOrder {
public static void main(String[] args) {
int number = 5837;
int temp = Math.abs(number);
while (temp > 0) {
int digit = temp % 10;
System.out.println(digit);
temp /= 10;
}
}
}
Output:
7
3
8
5
This happens because % 10 always accesses the last digit first.
Find the highest power of 10 needed to isolate the first digit. For 5837: divisor = 1000, then 5837 / 1000 = 5. After processing each digit, reduce the divisor.
public class ExtractDigitsOriginalOrder {
public static void main(String[] args) {
int number = 5837;
int temp = Math.abs(number);
int divisor = 1;
while (temp / divisor >= 10) {
divisor *= 10;
}
while (divisor > 0) {
int digit = temp / divisor;
System.out.println(digit);
temp %= divisor;
divisor /= 10;
}
}
}
Output:
5
8
3
7
For 5837:
| temp | divisor | digit |
|---|---|---|
| 5837 | 1000 | 5 |
| 837 | 100 | 8 |
| 37 | 10 | 3 |
| 7 | 1 | 7 |
Use right-to-left extraction when digit order does not matter, such as:
Use left-to-right extraction when processing order matters, such as:
O(d)O(1)Digit replacement changes every occurrence of one digit into another. Example: replace 2 with 9 in 1223042 → 1993049. This problem is more challenging because normal digit extraction works from right to left while the reconstructed number must preserve positional order.
Each extracted digit can be modified before being placed back at its correct decimal position.
public class ReplaceDigit {
public static void main(String[] args) {
int number = 1223042;
int oldDigit = 2;
int newDigit = 9;
int temp = Math.abs(number);
int result = 0;
int place = 1;
while (temp > 0) {
int digit = temp % 10;
if (digit == oldDigit) {
digit = newDigit;
}
result += digit * place;
place *= 10;
temp /= 10;
}
if (number < 0) {
result = -result;
}
System.out.println("Result: " + result);
}
}
Result: 1993049
Digits are processed from right to left.
| Extracted | Replaced | Place | Contribution |
|---|---|---|---|
| 2 | 9 | 1 | 9 |
| 4 | 4 | 10 | 40 |
| 0 | 0 | 100 | 0 |
| 3 | 3 | 1000 | 3000 |
| 2 | 9 | 10000 | 90000 |
| 2 | 9 | 100000 | 900000 |
| 1 | 1 | 1000000 | 1000000 |
Final result: 1993049
Without positional multiplication, extracted digits would lose their original place values — units multiply by 1, tens by 10, hundreds by 100, thousands by 1000.
Suppose 1232, replace 2 with 0 → result 1030. The arithmetic approach handles internal and trailing zero replacements correctly as an integer. However, replacing a leading digit with zero changes the visible digit count: 123 with 1→0 is mathematically 023, but as an integer that is 23 — leading zeros cannot be stored in an integer representation.
For formatting-oriented requirements, converting to a string can be simpler: String result = String.valueOf(number).replace('2', '9');. Use arithmetic when the purpose is to practice numeric logic. Use strings when textual representation is the actual requirement.
O(d)O(1) for the arithmetic versionMost problems in this chapter can be solved with a few reusable patterns.
int digit = number % 10;
number /= 10;
while (number > 0) {
int digit = number % 10;
// Process digit
number /= 10;
}
result = result * 10 + digit; — commonly used when reversing a number.
result += digit * place; place *= 10; — useful when modifying digits while keeping their original positions.
Accumulator initialization changes according to the problem.
| Problem | Recommended Initial Value |
|---|---|
| Sum of digits | 0 |
| Product of digits | 1 |
| Digit count | 0 |
| Reverse number | 0 |
| Largest digit | 0 |
| Smallest digit | 9 |
| Even digit count | 0 |
| Odd digit count | 0 |
| Frequency array | all 0 |
Incorrect initialization is one of the most common causes of wrong answers in digit-based programs.
Zero requires special attention because while (number > 0) does not execute when number == 0. Depending on the problem:
| Operation | Result for 0 |
|---|---|
| Number of digits | 1 |
| Sum of digits | 0 |
| Product of digits | Usually 0 |
| First digit | 0 |
| Last digit | 0 |
| Largest digit | 0 |
| Smallest digit | 0 |
| Even digit count | 1 |
| Odd digit count | 0 |
| Frequency of digit 0 | 1 |
The expected interpretation should follow the problem specification.
For digit analysis, the sign usually does not participate in the calculation. A common pattern is int temp = Math.abs(number);. For example, -5832 contains the digits 5, 8, 3, 2, not five symbols including the minus sign.
When the result itself should preserve the sign, as with number reversal, restore it after processing. Example: -1234 → -4321.
Digit-processing loops normally destroy their working value:
while (number > 0) {
number /= 10;
}
After the loop, number == 0. If the original value is required later, create a temporary variable: int temp = number;, then perform all digit operations on temp. This is especially important in problems such as:
Digit problems can often be solved both numerically and through strings.
Example: int digit = number % 10;. Advantages:
Best for: digit sums, reverse number, digit counts, maximum/minimum digit, frequency problems.
Example: String value = String.valueOf(number);. Advantages:
Best for: preserving leading zeros, character-oriented validation, formatting requirements.
For logic-development practice, arithmetic solutions should normally be understood first.
For a positive integer: digit = number % 10; number = number / 10;
Consider number = 5837. First iteration: digit = 5837 % 10 = 7, number = 5837 / 10 = 583. Second iteration: digit = 583 % 10 = 3, number = 583 / 10 = 58.
The number shrinks by approximately one decimal digit after each iteration. This is why most digit algorithms run in O(d) time.
If a number contains d digits, repeatedly dividing it by 10 requires approximately d iterations. Therefore Time Complexity = O(d). Since d ≈ log10(n) + 1, the same complexity can also be expressed as O(log10 n). In interview discussions, O(d) is often clearer because the algorithm directly processes each digit once.
Most arithmetic digit problems use only a few variables: digit, temp, sum, count, result. Therefore Space Complexity = O(1). Digit frequency also remains O(1) because its array always contains exactly ten elements.
This creates an infinite loop because the number never changes. Incorrect: while (number > 0) { int digit = number % 10; }. Correct: also include number /= 10; inside the loop.
If the original number is needed later, operate on a copy: int temp = number;
The standard positive-number loop does not process 0. Handle it separately when zero represents one actual digit.
Incorrect: int product = 0;. Correct: int product = 1;
Incorrect: int smallest = 0;. Correct: int smallest = 9; for ordinary positive decimal-digit scanning.
The expression reverse = reverse * 10 + digit; can exceed the range of an int. Use long or explicit overflow validation when the input range requires it.
Integer 00123 is effectively represented numerically as 123. If leading zeros matter, use a String.
The following pattern can solve many interview problems by changing only the digit-processing logic.
int temp = Math.abs(number);
while (temp > 0) {
int digit = temp % 10;
// Apply problem-specific logic here
temp /= 10;
}
Examples of problem-specific logic:
sum += digit;
product *= digit;
if (digit % 2 == 0) { evenCount++; }
if (digit > largest) { largest = digit; }
frequency[digit]++;
Understanding this reusable traversal is more valuable than memorizing separate programs.
If several statistics are required, avoid scanning the number repeatedly. A single loop can calculate: number of digits, sum, product, largest digit, smallest digit, even digit count, odd digit count.
public class DigitAnalysis {
public static void main(String[] args) {
int number = 583264;
int temp = Math.abs(number);
int count = 0;
int sum = 0;
int product = temp == 0 ? 0 : 1;
int largest = 0;
int smallest = temp == 0 ? 0 : 9;
int evenCount = 0;
int oddCount = 0;
if (temp == 0) {
count = 1;
evenCount = 1;
} else {
while (temp > 0) {
int digit = temp % 10;
count++;
sum += digit;
product *= digit;
if (digit > largest) {
largest = digit;
}
if (digit < smallest) {
smallest = digit;
}
if (digit % 2 == 0) {
evenCount++;
} else {
oddCount++;
}
temp /= 10;
}
}
System.out.println("Digits: " + count);
System.out.println("Sum: " + sum);
System.out.println("Product: " + product);
System.out.println("Largest: " + largest);
System.out.println("Smallest: " + smallest);
System.out.println("Even digits: " + evenCount);
System.out.println("Odd digits: " + oddCount);
}
}
Digits: 6
Sum: 28
Product: 5760
Largest: 8
Smallest: 2
Even digits: 4
Odd digits: 2
A single traversal is preferable when all statistics are required together because every digit is processed only once.
| Requirement | Core Logic |
|---|---|
| Extract last digit | number % 10 |
| Remove last digit | number / 10 |
| Count digits | increment while dividing by 10 |
| Sum digits | sum += digit |
| Product digits | product *= digit |
| Reverse number | reverse = reverse * 10 + digit |
| First digit | divide until < 10 |
| Last digit | number % 10 |
| Largest digit | compare using > |
| Smallest digit | compare using < |
| Even digit | digit % 2 == 0 |
| Odd digit | digit % 2 != 0 |
| Digit frequency | frequency[digit]++ |
| Remove final digit | number /= 10 |
| Replace digit | compare and reconstruct |
| Preserve input | process a temporary copy |
% 10 when you need the current last digit./ 10 when you need to remove that digit.number > 0.