Introduction

Finding the smallest and largest digit in a number is another classic Java programming exercise that builds upon the digit extraction techniques you've already learned throughout this series.

The core idea is simple:

  • Extract one digit at a time.
  • Compare it with the smallest and largest values found so far.
  • Update those values whenever necessary.

Although the algorithm itself is straightforward, it introduces an important programming pattern known as running comparison, where values are continuously updated while processing data sequentially.

Advertisement

This technique appears in many real-world algorithms, including:

  • Finding the maximum or minimum value in an array
  • Determining the highest or lowest score
  • Processing sensor data
  • Statistical calculations

In this guide, you'll learn:

  • Finding the smallest and largest digit using manual comparisons
  • Using Java's built-in Math.max() and Math.min() methods
  • Handling negative numbers correctly
  • A recursive implementation
  • Finding the second largest digit as an interview extension

Understanding the Problem

Suppose the input number is:

 
6392
 

Its individual digits are:

 
6
3
9
2
 

Among these:

  • Largest digit = 9
  • Smallest digit = 2

To determine these values, every digit must be examined exactly once.

While processing each digit, we continuously maintain two variables:

  • largest
  • smallest

Whenever a digit is larger than the current maximum, we update largest.

Whenever a digit is smaller than the current minimum, we update smallest.

This approach avoids sorting and requires only a single pass through the digits.


Method 1: Using a While Loop with Manual Comparison

This is the standard approach and the one most commonly asked in interviews.

The algorithm repeatedly extracts digits using modulus and division while updating the smallest and largest values.

Java Program

 
public class SmallestLargestDigit {

    public static void main(String[] args) {

        int num = 6392;

        int largest = Integer.MIN_VALUE;
        int smallest = Integer.MAX_VALUE;

        while (num != 0) {

            int digit = num % 10;

            if (digit > largest) {
                largest = digit;
            }

            if (digit < smallest) {
                smallest = digit;
            }

            num = num / 10;
        }

        System.out.println("Largest digit: " + largest);
        System.out.println("Smallest digit: " + smallest);
    }
}
 

Output

 
Largest digit: 9
Smallest digit: 2
 

Step-by-Step Execution

Let the input be:

 
6392
 

Initially:

Variable Value
largest Integer.MIN_VALUE
smallest Integer.MAX_VALUE

Iteration 1

Current number:

 
6392
 

Extract digit:

 
2
 

Update:

 
largest = 2

smallest = 2
 

Remaining number:

 
639
 

Iteration 2

Current number:

 
639
 

Extract digit:

 
9
 

Comparison:

 
9 > 2
 

Update:

 
largest = 9
 

Smallest remains:

 
2
 

Remaining number:

 
63
 

Iteration 3

Current number:

 
63
 

Extract digit:

 
3
 

Comparisons:

 
3 > 9   → No

3 < 2   → No
 

No updates occur.

Remaining number:

 
6
 

Iteration 4

Current number:

 
6
 

Extract digit:

 
6
 

Comparisons:

 
6 > 9   → No

6 < 2   → No
 

No updates occur.

The remaining number becomes:

 
0
 

The loop terminates.

Final values:

 
Largest digit = 9

Smallest digit = 2
 

Why Use Integer.MIN_VALUE and Integer.MAX_VALUE?

Notice the initialization:

 
int largest = Integer.MIN_VALUE;
int smallest = Integer.MAX_VALUE;
 

These constants represent the smallest and largest possible values that an int can store.

This guarantees that the very first digit processed will always update both variables correctly.

For example, if the first extracted digit is:

 
7
 

then:

 
7 > Integer.MIN_VALUE
 

is always true.

Similarly:

 
7 < Integer.MAX_VALUE
 

is also always true.

This makes the algorithm reliable regardless of the first digit encountered.

Time Complexity

  • Time Complexity: O(d)
  • Space Complexity: O(1)

where d is the number of digits in the input number.


Method 2: Using Math.max() and Math.min()

Java provides built-in utility methods that simplify comparisons.

Instead of writing explicit if statements, we can use:

  • Math.max()
  • Math.min()

to update the tracking variables.

Java Program

 
public class SmallestLargestUsingMath {

    public static void main(String[] args) {

        int num = 6392;

        int largest = Integer.MIN_VALUE;
        int smallest = Integer.MAX_VALUE;

        while (num != 0) {

            int digit = num % 10;

            largest = Math.max(largest, digit);

            smallest = Math.min(smallest, digit);

            num = num / 10;
        }

        System.out.println("Largest digit: " + largest);
        System.out.println("Smallest digit: " + smallest);
    }
}
 

Output

 
Largest digit: 9
Smallest digit: 2
 

How It Works

Instead of writing:

 
if (digit > largest) {
    largest = digit;
}
 

we simply write:

 
largest = Math.max(largest, digit);
 

Similarly,

instead of:

 
if (digit < smallest) {
    smallest = digit;
}
 

we write:

 
smallest = Math.min(smallest, digit);
 

Both approaches produce identical results.

The difference is only in readability.

Which Approach Should You Choose?

Both methods have:

  • The same algorithm
  • The same time complexity
  • The same memory usage

The Math.max() / Math.min() version is generally preferred in production code because it is shorter, cleaner, and easier to read.

However, beginners often find the manual comparison version easier to understand because it clearly shows each comparison step.

Time Complexity

  • Time Complexity: O(d)
  • Space Complexity: O(1)

where d is the number of digits in the input number.

Method 3: Using Recursion

The same logic used in the iterative solution can also be implemented using recursion.

Instead of processing each digit inside a loop, each recursive call processes one digit and then calls itself with the remaining part of the number.

Java Program

 
public class SmallestLargestRecursion {

    static int largest = Integer.MIN_VALUE;
    static int smallest = Integer.MAX_VALUE;

    static void findDigits(int num) {

        if (num == 0) {
            return;
        }

        int digit = num % 10;

        largest = Math.max(largest, digit);
        smallest = Math.min(smallest, digit);

        findDigits(num / 10);
    }

    public static void main(String[] args) {

        int num = 6392;

        findDigits(num);

        System.out.println("Largest digit: " + largest);
        System.out.println("Smallest digit: " + smallest);
    }
}
 

Output

 
Largest digit: 9
Smallest digit: 2
 

How It Works

Suppose the input is:

 
6392
 

The recursive calls occur as follows:

 
findDigits(6392)
 

 
digit = 2
 

 
findDigits(639)
 

 
digit = 9
 

 
findDigits(63)
 

 
digit = 3
 

 
findDigits(6)
 

 
digit = 6
 

 
findDigits(0)
 

The base case:

 
if (num == 0)
 

stops the recursion.

Throughout this process, the static variables largest and smallest are continuously updated.

Design Limitation

Like several earlier recursive examples in this series, this solution uses static variables.

That means:

 
largest
smallest
 

retain their values even after the method finishes.

If the method is called again without resetting these variables, incorrect results may occur.

A cleaner production-quality solution would pass these values through recursive parameters or return an object containing both values.

Time Complexity

  • Time Complexity: O(d)
  • Space Complexity: O(d)

where d is the number of digits.


Method 4: Handling Negative Numbers Correctly

Negative numbers require special handling.

For example:

 
-6392
 

If processed directly, Java's modulus operator produces negative remainders:

 
-6392 % 10
 

which gives:

 
-2
 

This is not useful because digits are normally treated as positive values.

The simplest solution is to convert the number to its absolute value before extracting digits.

Java Program

 
public class SmallestLargestNegative {

    public static void main(String[] args) {

        int num = -6392;

        num = Math.abs(num);

        int largest = Integer.MIN_VALUE;
        int smallest = Integer.MAX_VALUE;

        while (num != 0) {

            int digit = num % 10;

            largest = Math.max(largest, digit);
            smallest = Math.min(smallest, digit);

            num = num / 10;
        }

        System.out.println("Largest digit: " + largest);
        System.out.println("Smallest digit: " + smallest);
    }
}
 

Output

 
Largest digit: 9
Smallest digit: 2
 

Why Use Math.abs()?

The sign (-) is not considered a digit.

By converting:

 
-6392
 

to:

 
6392
 

the program correctly analyzes only the digits of the number.

This same technique is used in many digit-based algorithms, including:

Time Complexity

  • Time Complexity: O(d)
  • Space Complexity: O(1)

Extension: Finding the Second Largest Digit

A common interview follow-up is:

"Can you also find the second largest digit?"

This problem is slightly more challenging because we must keep track of two values instead of one.

Java Program

 
public class SecondLargestDigit {

    public static void main(String[] args) {

        int num = 6392;

        int largest = Integer.MIN_VALUE;
        int secondLargest = Integer.MIN_VALUE;

        while (num != 0) {

            int digit = num % 10;

            if (digit > largest) {

                secondLargest = largest;
                largest = digit;

            } else if (digit > secondLargest && digit != largest) {

                secondLargest = digit;
            }

            num = num / 10;
        }

        System.out.println("Largest digit: " + largest);
        System.out.println("Second largest digit: " + secondLargest);
    }
}
 

Output

 
Largest digit: 9
Second largest digit: 6
 

How It Works

Suppose the digits are:

 
6
3
9
2
 

Initially:

 
largest = Integer.MIN_VALUE

secondLargest = Integer.MIN_VALUE
 

Processing:

 
6
 

updates:

 
largest = 6
 

Processing:

 
9
 

produces:

 
secondLargest = 6

largest = 9
 

Processing:

 
3
 

does not change either value.

Processing:

 
2
 

also leaves the values unchanged.

Final result:

 
Largest digit = 9

Second largest digit = 6
 

Why Check digit != largest?

Consider the number:

 
9954
 

Without this condition:

 
digit != largest
 

the second occurrence of 9 could incorrectly become the second largest value.

The comparison ensures that the second largest digit is distinct from the largest digit.

This is one of the most common mistakes in interview solutions.

Time Complexity

  • Time Complexity: O(d)
  • Space Complexity: O(1)

How Java Handles This Internally (Memory Concept)

Methods 1, 2, and 4

The variables:

  • num
  • digit
  • largest
  • smallest

are primitive int values stored in the JVM stack.

Each loop iteration simply updates these variables.

No heap memory is allocated.

Even:

 
Math.max()
Math.min()
 

perform simple primitive comparisons internally and do not create new objects.


Method 3

The recursive implementation behaves differently.

The variables:

 
largest

smallest
 

are declared as static.

They belong to the class rather than to individual function calls.

Every recursive call updates the same shared variables.

Meanwhile, each recursive call creates its own stack frame containing:

 
num
 

After the base case is reached, the stack frames are removed one by one.


Integer Constants

The values:

 
Integer.MIN_VALUE

Integer.MAX_VALUE
 

are predefined constants provided by Java.

They represent the smallest and largest values an int can store:

 
Integer.MIN_VALUE = -2,147,483,648

Integer.MAX_VALUE = 2,147,483,647
 

Using these constants guarantees correct initialization for running comparisons.


Real-Life Analogy: Finding the Tallest and Shortest Person

Imagine you're walking through a line of people.

As you meet each person:

  • If they're taller than everyone you've seen so far, they become the new tallest.
  • If they're shorter than everyone you've seen so far, they become the new shortest.

You never need to compare everyone repeatedly.

You simply update your current tallest and shortest records as you move through the line.

Finding the largest and smallest digit works in exactly the same way.

Each digit is examined once, and the running maximum and minimum values are updated whenever a better candidate is found.

Comparison of All Methods

Method Readability Handles Negative Numbers Automatically? Time Complexity Space Complexity Best Used When
Manual Comparison Very clear and explicit ❌ No O(d) O(1) Learning the comparison logic and interviews
Math.max() / Math.min() Concise and readable ❌ No O(d) O(1) Production code and cleaner implementations
Recursion Good for demonstrating recursion ❌ No O(d) O(d) Practicing recursive programming
Second Largest Extension Moderate complexity ❌ No O(d) O(1) Interview follow-up questions

Note: Here, d represents the number of digits in the input number.


Best Practices

  • Initialize the tracking variables correctly:

     
    int largest = Integer.MIN_VALUE;
    int smallest = Integer.MAX_VALUE;
     

    This guarantees that the first digit processed will always update both values correctly.

  • Prefer Math.max() and Math.min() when writing production code because they make the comparison logic shorter and easier to read.
  • If negative numbers are possible, convert the input to its absolute value before extracting digits:

     
    num = Math.abs(num);
     
  • When finding the second largest digit, ensure that duplicate occurrences of the largest digit are not mistakenly treated as the second largest value.
  • If this logic is needed repeatedly throughout a larger application, encapsulate it inside a reusable method rather than writing it directly inside main().
  • Test your solution using different types of inputs, including:
    • Single-digit numbers
    • Numbers containing repeated digits
    • Numbers containing zero
    • Negative numbers

Common Mistakes Beginners Make

1. Incorrectly Initializing the Tracking Variables

Some beginners write:

 
int largest = 0;
 

instead of:

 
int largest = Integer.MIN_VALUE;
 

Although digits range only from 0 to 9, using Integer.MIN_VALUE is a better programming practice because it generalizes correctly to other maximum-finding problems.


2. Forgetting to Handle Negative Numbers

Processing a negative number directly may extract negative remainders.

Always write:

 
num = Math.abs(num);
 

before processing the digits.


3. Incorrectly Handling Duplicate Digits

Suppose the input is:

 
9954
 

The largest digit is:

 
9
 

The second largest distinct digit should be:

 
5
 

Not:

 
9
 

This is why the condition:

 
digit != largest
 

is necessary.


4. Using >= Instead of >

Writing:

 
if (digit >= largest)
 

instead of:

 
if (digit > largest)
 

can change the behavior when duplicate digits are encountered.

Always think carefully about whether duplicates should update the tracking variables.


5. Not Testing Edge Cases

Many solutions work correctly for:

 
6392
 

but fail for inputs such as:

 
5555
 

or

 
1000
 

Always test:

  • Repeated digits
  • Single-digit numbers
  • Numbers containing zeros
  • Negative numbers

Expert Tips for Interviews

A strong interview answer might sound like this:

"To find the smallest and largest digit, I repeatedly extract digits using modulus and division while maintaining two running variables initialized to Integer.MIN_VALUE and Integer.MAX_VALUE. After extracting each digit, I update the running maximum and minimum using either manual comparisons or Math.max() and Math.min(). If asked to find the second largest digit, I maintain an additional variable and carefully handle duplicate digits so that repeated occurrences of the largest value are not incorrectly treated as the second largest."

Mentioning duplicate-digit handling without being prompted demonstrates attention to edge cases, which interviewers often appreciate.


Pros and Cons

Manual Comparison

Pros

  • ✅ Easy to understand
  • ✅ Shows the comparison logic explicitly
  • ✅ Good for beginners and interviews

Cons

  • ❌ Slightly more verbose
  • ❌ Requires multiple if statements

Using Math.max() and Math.min()

Pros

  • ✅ Cleaner code
  • ✅ Easier to read
  • ✅ Preferred in production code

Cons

  • ❌ Slightly less explicit for beginners learning comparison logic

Using Recursion

Pros

  • ✅ Demonstrates recursive programming
  • ✅ Reuses familiar recursion patterns
  • ✅ Useful for loop-free interview questions

Cons

  • ❌ Uses additional stack space
  • ❌ Relies on static variables in this implementation
  • ❌ Less practical than the iterative solution

Second Largest Digit Extension

Pros

  • ✅ Common interview follow-up
  • ✅ Demonstrates handling multiple running values
  • ✅ Encourages careful edge-case handling

Cons

  • ❌ Slightly more complex comparison logic
  • ❌ Duplicate digits require additional care

Frequently Asked Questions

1. How do I find the largest digit in a number?

Extract each digit using % and /, compare it with the current largest value, and update the result whenever a larger digit is found.


2. How do I find the smallest digit in a number?

Follow the same approach used for the largest digit, but update the tracking variable whenever a smaller digit is encountered.


3. Can I use Math.max() and Math.min()?

Yes.

They provide a cleaner alternative to manual if statements while producing exactly the same result.


4. How do I handle negative numbers?

Convert the number to its absolute value first:

 
num = Math.abs(num);
 

Then process its digits normally.


5. How do I find the second largest digit?

Maintain two variables:

  • largest
  • secondLargest

Whenever a new maximum is found, move the previous largest value into secondLargest.

Also ensure duplicate largest digits are ignored.


6. Why use Integer.MIN_VALUE instead of 0?

Integer.MIN_VALUE guarantees that the first digit always updates the largest value correctly.

It is also a better general-purpose technique for maximum-finding algorithms.


7. What is the time complexity?

Each digit is processed exactly once.

  • Time Complexity: O(d)

where d is the number of digits.


8. Can this problem be solved using recursion?

Yes.

The recursive solution processes one digit per recursive call while updating the running smallest and largest values.


9. What happens if the input contains only one digit?

That single digit is both:

  • The largest digit
  • The smallest digit

For example:

7

Largest = 7

Smallest = 7


10. Is this a common interview question?

Yes.

It is frequently asked because it tests:

  • Digit extraction
  • Running comparisons
  • Edge-case handling

It is also commonly followed by the "second largest digit" variation.


11. Can I solve this without using a loop?

Yes.

Recursion can replace the loop by processing one digit in each recursive call until the base case is reached.


12. What happens if all digits are the same?

For example:

5555

Then:

  • Largest digit = 5
  • Smallest digit = 5

For the second largest distinct digit, no valid second value exists.

Your implementation should handle this situation explicitly—for example, by displaying a message such as "Second largest digit not found" or by checking whether secondLargest was ever updated.