Return the second largest distinct value in an array, ideally in one pass.
Track largest and secondLargest together. For each element: if it beats largest, secondLargest becomes the old largest and largest updates; else if it is between secondLargest and largest (and, for the distinct variant, not equal to largest), update secondLargest. O(n). Sorting works but is slower.
public static int secondLargest(int[] a) {
int first = Integer.MIN_VALUE, second = Integer.MIN_VALUE;
for (int x : a) {
if (x > first) { second = first; first = x; }
else if (x > second && x != first) { second = x; }
}
return second;
}function secondLargest(a) {
let first = -Infinity, second = -Infinity;
for (const x of a) {
if (x > first) { second = first; first = x; }
else if (x > second && x !== first) { second = x; }
}
return second;
}def second_largest(a):
first = second = float('-inf')
for x in a:
if x > first:
second, first = first, x
elif x > second and x != first:
second = x
return secondTracking the top two values in one pass is how you find, say, the two slowest operations from a result stream without a full sort.
For [20, 20, 10] your code returns 20, but the interviewer wanted the second largest DISTINCT value. Fix?