Answer
Second Largest Number in an Array
Method 1: Single Pass — Optimal O(n)
Java
public static int secondLargest(int[] arr) {
if (arr == null || arr.length < 2) {
throw new IllegalArgumentException("Array must have at least 2 elements");
}
int largest = Integer.MIN_VALUE;
int secondLargest = Integer.MIN_VALUE;
for (int num : arr) {
if (num > largest) {
secondLargest = largest; // old largest becomes second
largest = num; // new largest
} else if (num > secondLargest && num != largest) {
secondLargest = num; // update second largest
}
}
if (secondLargest == Integer.MIN_VALUE) {
throw new RuntimeException("No distinct second largest element");
}
return secondLargest;
}
int[] arr = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3};
System.out.println(secondLargest(arr)); // 6
Method 2: Sorting (Simple but O(n log n))
Java
public static int secondLargestBySorting(int[] arr) {
int[] sorted = Arrays.copyOf(arr, arr.length);
Arrays.sort(sorted); // ascending
// Find second distinct from end
int largest = sorted[sorted.length - 1];
for (int i = sorted.length - 2; i >= 0; i--) {
if (sorted[i] != largest) {
return sorted[i];
}
}
throw new RuntimeException("All elements are equal");
}
Method 3: Using TreeSet (removes duplicates + sorted)
Java
public static int secondLargestWithSet(int[] arr) {
TreeSet<Integer> set = new TreeSet<>();
for (int n : arr) set.add(n); // automatically sorted, no duplicates
set.pollLast(); // remove largest
return set.last(); // new last = second largest
}
Method 4: Java 8 Streams
Java
public static OptionalInt secondLargestStream(int[] arr) {
return Arrays.stream(arr)
.distinct() // remove duplicates
.sorted() // ascending
.toArray() // to array
[arr.length - 2]; // second from end
// Better approach:
return Arrays.stream(arr)
.boxed()
.distinct()
.sorted(Comparator.reverseOrder())
.skip(1) // skip largest
.findFirst()
.orElseThrow();
}
Complete Solution with Tests
Java
public class SecondLargestTest {
@Test
public void testBasic() {
assertEquals(6, secondLargest(new int[]{3, 1, 4, 1, 5, 9, 2, 6}));
}
@Test
public void testWithDuplicates() {
assertEquals(5, secondLargest(new int[]{5, 5, 3, 9, 9}));
}
@Test
public void testTwoElements() {
assertEquals(1, secondLargest(new int[]{5, 1}));
}
@Test
public void testNegativeNumbers() {
assertEquals(-3, secondLargest(new int[]{-1, -3, -5, -2}));
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testTooSmallArray() {
secondLargest(new int[]{5});
}
}
Variation: Second Smallest
Java
public static int secondSmallest(int[] arr) {
int smallest = Integer.MAX_VALUE, second = Integer.MAX_VALUE;
for (int n : arr) {
if (n < smallest) { second = smallest; smallest = n; }
else if (n < second && n != smallest) { second = n; }
}
return second;
}
