Java ProgramsArraysFind Second Largest Element in an Array

Find Second Largest Element in an Array in Java

beginner·  Arrays  ·  Array

Problem

The second largest element is the biggest value in the array after excluding the single largest one.

Given an array of integers, find its second largest element.

Input
[12, 45, 3, 68, 22, 7]
Output
Second largest: 45

Java Program

Java
public class SecondLargest { public static void main(String[] args) { int[] arr = {12, 45, 3, 68, 22, 7}; int largest = Integer.MIN_VALUE, secondLargest = Integer.MIN_VALUE; for (int num : arr) { if (num > largest) { secondLargest = largest; // old largest slides down largest = num; } else if (num > secondLargest && num != largest) { secondLargest = num; } } System.out.println("Second largest: " + secondLargest); } }

Output

Second largest: 45

Core Logic

Tracking both the largest and second-largest value at once, updating both together whenever a new largest is found, gets the answer in a single pass.

How It Works
  1. 1largest and secondLargest both start at Integer.MIN_VALUE, so even negative array values update them correctly.
  2. 2When a number beats largest, the old largest value slides down into secondLargest before largest is updated.
  3. 3When a number doesn't beat largest but still beats secondLargest (and isn't a duplicate of largest), only secondLargest updates.
  4. 4After the full pass, secondLargest holds the answer.
For [12, 45, 3, 68, 22, 7], largest/secondLargest update to 12/MIN, then 45/12, then stay put until 68/45 — leaving secondLargest at 45.
💡

Key Point: The num != largest check matters — without it, a duplicate of the largest value would incorrectly overwrite secondLargest with a copy of the largest instead of the true runner-up.

Complexity
Time Complexity: O(n)Space Complexity: O(1)

Why: A single pass tracks two running values, so the extra memory stays constant regardless of array size.

Key Concepts

for-each looprunning two maximums

Approach 2: Sorting

Java
import java.util.Arrays; public class SecondLargestSorted { public static void main(String[] args) { int[] arr = {12, 45, 3, 68, 22, 7}; int[] sorted = arr.clone(); // sort a copy, not the caller's original array Arrays.sort(sorted); System.out.println("Second largest: " + sorted[sorted.length - 2]); // second-from-last after sorting } }

Output

Second largest: 45

Core Logic

Sorting a copy of the array puts every value in order, so the second largest is simply the second-from-last element.

How It Works
  1. 1arr.clone() copies the array first, so sorting doesn't disturb the caller's original array.
  2. 2Arrays.sort(sorted) puts the copy into ascending order.
  3. 3sorted[sorted.length - 2] reads the second-from-last element, which is the second largest value.
Sorting [12, 45, 3, 68, 22, 7] gives [3, 7, 12, 22, 45, 68], and the second-from-last element is 45.
💡

Key Point: This assumes the largest value appears only once — with duplicates at the top, the second-from-last element after sorting could just be another copy of the largest, unlike the single-pass version's explicit duplicate check.

Complexity
Time Complexity: O(n log n)Space Complexity: O(n)

Why: clone() copies every element into a new array, and sorting that copy costs O(n log n) comparisons.

Key Concepts

Arrays.sort()array cloning

Approach 3: Java 8

Java
import java.util.Arrays; import java.util.Comparator; public class SecondLargestStream { public static void main(String[] args) { int[] arr = {12, 45, 3, 68, 22, 7}; // Sorts the distinct values descending and skips the largest int secondLargest = Arrays.stream(arr) .boxed() .distinct() .sorted(Comparator.reverseOrder()) .skip(1) .findFirst() .orElseThrow(); System.out.println("Second largest: " + secondLargest); } }

Output

Second largest: 45

Core Logic

Sorting the distinct values in descending order and skipping the first one lands directly on the second largest.

How It Works
  1. 1Arrays.stream(arr).boxed() converts the int[] into a Stream<Integer>, since sorted() with a custom comparator needs boxed values.
  2. 2.distinct() removes duplicate values, so a repeated largest value doesn't occupy the runner-up spot.
  3. 3.sorted(Comparator.reverseOrder()) puts the distinct values into descending order.
  4. 4.skip(1) drops the largest value, and .findFirst() returns whatever comes next — the second largest.
For [12, 45, 3, 68, 22, 7], sorting the distinct values descending gives [68, 45, 22, 12, 7, 3]; skipping the first leaves 45 as the answer.
💡

Key Point: .distinct() here does the same job as the single-pass version's num != largest check — both exist to stop a duplicate of the largest value from being reported as the runner-up.

Complexity
Time Complexity: O(n log n)Space Complexity: O(n)

Why: distinct() and sorted() together still perform a comparison sort over the boxed values, and boxing to Integer plus the sort's internal buffer both cost O(n) space.

Key Concepts

Streamdistinct()sorted()skip()

Related Programs