Easy–medium · edge cases
Second Largest
Find the largest number you already know how to find. The second largest is the same problem with one extra variable — and a trap about what happens when every number is identical.
At a glanceTrack the largest and the second-largest distinct value in one pass; when every element is equal there is no second largest, and the answer is the word none.
Problem
Input: The first line is an integer n (2 ≤ n ≤ 1000). The second line holds n integers separated by spaces (−1000 ≤ ai ≤ 1000).
Output: The second largest distinct value. If every number is the same, print none.
Samples:
| Input | Output |
|---|---|
5 | 7 |
4 | none |
3 | -5 |
"Distinct" is the whole difficulty. With 3 9 2 9 7 the answer is 7, not 9 — 9 appears twice but it is still just one value.
Your solution
Custom input for "Run my input"
Judging runs in your browser against hidden tests. A runaway loop is cut off after 3 seconds — still, make sure every loop has an exit. Your code is saved in this browser as you type.
Stuck? Hints
Hint 1 — Start from the maximum you already know
One variable big holds the largest seen so far. Add a second one, second. Every time a new number beats big, the old big gets demoted into second — that single line is the entire trick.
Hint 2 — Two branches, not one
If x > big, shift. Otherwise, if x is smaller than big but bigger than second, it becomes the new second. That second branch is what makes duplicates harmless: when x == big neither branch fires, so a repeated maximum never overwrites the runner-up.
Hint 3 — Where do you start the two variables?
Not 0. The inputs can be negative, so 0 would look like a valid "largest" that never existed. Use a value below any legal input — -1000000000 — and at the end check whether second is still that sentinel: if it is, there was no second distinct value.
Solution (try it first!)
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int big = -1000000000, second = -1000000000;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
if (x > big) {
second = big;
big = x;
} else if (x < big && x > second) {
second = x;
}
}
if (second == -1000000000) cout << "none" << endl;
else cout << second << endl;
return 0;
}
Notice what you did not do: nothing was stored, nothing was sorted. One pass, two variables, done — O(n) time and O(1) memory. The same demote-and-shift shape gives you the third largest, the two smallest, and the best two scores in a game. Next, put that O(1) memory to work on a problem where the array must actually be reordered: Bubble Sort.
Deep dive
Why this works
One pass, two variables, and the job is done — no array, no sorting. That demote-and-shift shape is the skeleton of every Top-K problem you will meet.
The cost
O(n) time, O(1) memory. Sorting first and taking the runner-up is O(n log n) plus a copy of the data — spreading the whole deck to read one card.
Where it goes wrong
- Starting
secondat 0 prints 0 for all-negative input — an answer that does not exist in the data. - Writing only the
x > bigbranch and forgettingx < big && x > secondleavessecondstuck on the old maximum when values repeat.
Next step
Now let a rule run itself and watch where it lands: Collatz Steps.
Two things to remember
- Two variables, one demotion: when the new king takes the throne, the old one becomes second.
- The sentinel must be smaller than any legal input, or it will masquerade as an answer.
🐞 This version fails — open it and try
second starts at 0 — with all-negative input it prints 0
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int big = 0, second = 0; // assumes the input is positive
for (int i = 0; i < n; i++) {
int x;
cin >> x;
if (x > big) {
second = big;
big = x;
} else if (x < big && x > second) {
second = x;
}
}
cout << second << endl;
return 0;
}