Back to Arrays
Q4Question 4 of 109

Find the largest element in an array

Key Concepts
  • Seed a max variable with the first element, then scan the rest of the array once and update max whenever a larger value appears.
  • The algorithm runs in O(n) time because every element is visited exactly once, and O(1) extra space because only one tracking variable is used.
  • You cannot do better than O(n) because skipping any element risks missing the largest.
  • For money always use BigDecimal and compare with compareTo, never double and the greater-than operator.
  • Guard the empty array by throwing IllegalArgumentException rather than returning a misleading zero.
  • Seeding with the first real element is safer than seeding with zero or Integer.MIN_VALUE, especially when all values could be negative.

Definition

Start by assuming the first element is the biggest, then walk the array once and upgrade max whenever something larger appears.
  • Linear scan – you visit each element exactly once from left to right, so the algorithm is O(n) time.
  • Tracking variable – a single variable max remembers the biggest value seen so far, giving O(1) extra space.
  • Seeding – initialise max with the first element, not with zero, because amounts can be negative debits.
  • Comparison – for BigDecimal use compareTo where a positive result means the left value is larger, because BigDecimal does not support the > operator.
  • Edge case – an empty array has no largest element, so throw IllegalArgumentException rather than returning a misleading value.

Imagine Rajesh wants to know the single biggest deposit he made all year at National Bank of India. He takes his passbook, points at the first deposit and says "this is the biggest so far." Then he reads each later deposit one by one. Every time he sees a deposit bigger than the one he is pointing at, he moves his finger to that new bigger one. When he reaches the end, his finger is on the biggest deposit of the year.

Understanding the Concepts

What is the problem?

Given an array of numbers, find the single largest element. In a banking context, Rajesh has a list of transaction amounts for the month on his savings account SAV2001 at National Bank of India, and the statement page needs to highlight the biggest single transaction.

Why is a linear scan the right approach?

You cannot do better than O(n) because every element could potentially be the largest, and if you skip even one element, that element might have been the answer. Sorting the array first and picking the last element would work but costs O(n log n), which is wasteful when a single pass suffices.

How does the algorithm work?

Seed a variable max with the first element. Then iterate from the second element to the end. For each element, compare it with max. If the element is larger, assign it to max. When the loop finishes, max holds the largest value.

JAVA
package com.bank.service;

import java.math.BigDecimal;

public class TransactionAnalyzer {

    public static BigDecimal findLargestTransaction(BigDecimal[] amounts) {
        if (amounts == null || amounts.length == 0) {
            throw new IllegalArgumentException("No transactions to analyze");
        }
        BigDecimal max = amounts[0];
        for (int i = 1; i < amounts.length; i++) {
            if (amounts[i].compareTo(max) > 0) {
                max = amounts[i];
            }
        }
        return max;
    }

    public static void main(String[] args) {
        BigDecimal[] monthlyAmounts = {
            new BigDecimal("15000.00"),
            new BigDecimal("42500.75"),
            new BigDecimal("8000.00"),
            new BigDecimal("67200.50"),
            new BigDecimal("3100.25")
        };
        BigDecimal largest = findLargestTransaction(monthlyAmounts);
        System.out.println("Largest transaction for SAV2001: Rs." + largest);
    }
}
TEXT
Largest transaction for SAV2001: Rs.67200.50

Why seed with the first element instead of zero?

Seeding with zero gives the wrong answer when all values are negative. In banking, a debit-only view might contain values like -500, -1200, and -300. The largest is -300, but if max starts at zero it would never be replaced and the method would return zero, which is not even in the array. Seeding with the first real element is always correct regardless of the sign of the values.

JAVA
// Wrong: seeding with zero
BigDecimal max = BigDecimal.ZERO;
BigDecimal[] debits = { new BigDecimal("-500"), new BigDecimal("-1200") };
// max stays 0, which is wrong

// Correct: seeding with the first element
BigDecimal maxCorrect = debits[0]; // -500
// after loop, maxCorrect is -500, which is correct

Why use BigDecimal and compareTo for money?

The double type introduces rounding errors that are unacceptable in finance. For example, 0.1 + 0.2 in double arithmetic is 0.30000000000000004, not 0.3. BigDecimal stores the exact decimal value. Because BigDecimal does not support the > operator, you compare with compareTo, which returns a positive number when the left value is larger, zero when equal, and a negative number when smaller.

JAVA
BigDecimal a = new BigDecimal("42500.75");
BigDecimal b = new BigDecimal("67200.50");
int result = a.compareTo(b); // result is negative, meaning a < b

What about the empty array edge case?

An empty array has no largest element. Returning zero or BigDecimal.ZERO would be misleading because it implies a zero-rupee transaction occurred. Throwing IllegalArgumentException with a clear message forces the calling code to handle the absence explicitly.

JAVA
if (amounts == null || amounts.length == 0) {
    throw new IllegalArgumentException("No transactions to analyze");
}

What is the time and space complexity?

  • Time: O(n) because the loop visits each element exactly once.
  • Space: O(1) because only one tracking variable max is used regardless of array size.
  • You cannot beat O(n) because any skipped element could be the largest.

What are common mistakes?

The most common mistake is seeding max with zero or Integer.MIN_VALUE instead of the first element. Another mistake is using equals instead of compareTo for BigDecimal, which fails when the scale differs. A third mistake is forgetting to guard the empty array.

JAVA
// Mistake 1: seeding with Integer.MIN_VALUE for BigDecimal
// BigDecimal has no MIN_VALUE constant like int does

// Mistake 2: using == instead of compareTo for BigDecimal
if (amounts[i] == max) { } // compares references, not values

// Correct: use compareTo
if (amounts[i].compareTo(max) > 0) { max = amounts[i]; }

How does this compare to using streams?

Java streams offer a concise alternative with Arrays.stream(amounts).max(Comparator.naturalOrder()), which returns an Optional. The stream version is elegant but creates iterator objects and boxes primitives, so for a tight inner loop on large arrays the manual scan is faster. For typical business code the stream version is perfectly fine.

JAVA
import java.util.Arrays;
import java.util.Comparator;
import java.util.Optional;

Optional<BigDecimal> largest = Arrays.stream(amounts)
    .max(Comparator.naturalOrder());
largest.ifPresent(val -> System.out.println("Largest: Rs." + val));

What should a senior engineer know?

A senior engineer knows that this problem is the building block for many scan-based algorithms: finding the minimum, finding the second largest, and finding both min and max in one pass all follow the same pattern. The senior also knows that for very large distributed datasets, the scan parallelises trivially because each partition can find its local maximum and the global maximum is the max of the local maxima. In a banking batch job processing millions of transactions, this partition-and-merge strategy lets the scan run across multiple threads or nodes.

Visual Overview

DIAGRAM
  amounts[]:  15000  42500  8000  67200  3100
               │
               ▼
  max = 15000  (seed with first element)
               │
         ┌─────┴─────┐
         │  i = 1     │  42500 > 15000?  YES → max = 42500
         │  i = 2     │   8000 > 42500?  NO
         │  i = 3     │  67200 > 42500?  YES → max = 67200
         │  i = 4     │   3100 > 67200?  NO
         └─────┬─────┘
               ▼
  Result: max = 67200.50

Key Takeaway

Finding the largest element in an array is a classic linear scan problem that I solve in a single pass with constant extra space. I seed a maximum variable with the first element of the array, and then I walk through the rest of the array, comparing each element with my current maximum and upgrading the maximum whenever I find something bigger. By the time I reach the end, the maximum variable holds the largest value.

In my banking project at National Bank of India, I used exactly this pattern to show a customer their highest single transaction for the month on their statement page. Rajesh's account SAV2001 has a list of transaction amounts, and I scan that list to find the biggest one. Because this is money, I store every amount as a BigDecimal and compare using the compareTo method, where a positive result means the left value is larger, since BigDecimal does not support the plain greater-than operator.

One nuance I always mention is the empty case. If the account has no transactions for the month, there is no largest value to return, so instead of returning a misleading zero I throw an IllegalArgumentException with a clear message. That way the calling code knows there was genuinely no data rather than believing a zero-rupee transaction occurred.

The seeding choice matters too. I seed with the first real element rather than zero, because a debit-only view could contain only negative amounts and seeding with zero would give a wrong answer that is not even in the array. This small guard is the difference between toy code and production code in a financial system.

Remember one sentence: seed max with the first element, scan once, and update whenever you find something bigger.

---

Share
Use ← → arrow keys to navigate