The challenge

Given an array of positive integers, return the number with the most digits. If two or more numbers share the highest digit count, return the first one that appears in the array.

Examples:

findLongest(new int[]{1, 10, 100});     // → 100
findLongest(new int[]{9000, 8, 800});   // → 9000
findLongest(new int[]{8, 900, 500});    // → 900

This puzzle appears on Codewars and HackerRank in Java tracks. The first-match tie-breaker is the part candidates miss most often.

Solution 1: classic for-loop

The straight-line, no-tricks version. Works on any Java version from 1.5 onwards:

public class Solution {
    public static int findLongest(int[] nums) {
        int longest = nums[0];
        int longestDigits = String.valueOf(nums[0]).length();

        for (int i = 1; i < nums.length; i++) {
            int digits = String.valueOf(nums[i]).length();
            if (digits > longestDigits) {
                longest = nums[i];
                longestDigits = digits;
            }
        }
        return longest;
    }
}

Why this works: Track the current winner and its digit count. Only replace when the new value has strictly more digits — that keeps the first match on ties.

Solution 2: Stream.reduce (Java 8+)

Functional style, but be careful with the tie-breaker:

import java.util.Arrays;

public class Solution {
    public static int findLongest(int[] nums) {
        return Arrays.stream(nums)
                     .reduce((a, b) ->
                         String.valueOf(b).length() > String.valueOf(a).length() ? b : a)
                     .getAsInt();
    }
}

Why this works: reduce walks left-to-right. The lambda only returns b when it has strictly more digits than a, so equal-digit numbers never displace the accumulator. Note: Stream.max would return the last element on ties, which fails the requirement.

Solution 3: Math.log10 (no String allocation)

If you are running this on millions of integers, the String.valueOf calls become the bottleneck. Use logarithms instead:

public class Solution {
    public static int findLongest(int[] nums) {
        int longest = nums[0];
        int longestDigits = (int) Math.log10(nums[0]) + 1;

        for (int i = 1; i < nums.length; i++) {
            int digits = (int) Math.log10(nums[i]) + 1;
            if (digits > longestDigits) {
                longest = nums[i];
                longestDigits = digits;
            }
        }
        return longest;
    }
}

Math.log10(100) is 2.0, and 100 has 3 digits — so (int) Math.log10(n) + 1 gives the digit count with no String allocation. The cast truncates toward zero, which works for all positive integers.

Caveat: Math.log10(0) is -Infinity. The challenge guarantees positive integers, so we do not guard against that.

Complexity

Solution Time Space
for-loop O(n × d) O(1) extra
Stream.reduce O(n × d) O(1) extra
Math.log10 O(n) O(1) extra

Where n is array length and d is the average digit count. For 32-bit ints d ≤ 10, so all three are effectively linear.

Edge cases

  • Single-element array: findLongest(new int[]{42}) returns 42.
  • All same digit count: findLongest(new int[]{10, 20, 30}) returns 10 (first wins).
  • Empty array: all three solutions throw — guard with if (nums.length == 0) if your input source allows it.

Test cases

import static org.junit.jupiter.api.Assertions.assertEquals;

assertEquals(100,   Solution.findLongest(new int[]{1, 10, 100}));
assertEquals(9000,  Solution.findLongest(new int[]{9000, 8, 800}));
assertEquals(900,   Solution.findLongest(new int[]{8, 900, 500}));
assertEquals(40000, Solution.findLongest(new int[]{3, 40000, 100}));
assertEquals(100000,Solution.findLongest(new int[]{1, 200, 100000}));
assertEquals(42,    Solution.findLongest(new int[]{42}));