Read the problem before touching the keyboard
Most failed coding rounds fail in the first two minutes: the candidate starts typing a solution to a problem they have not fully read. Slow down and write these five things down, as a comment above the function or out loud, before any code.
- 1Restate it
One sentence, in your own words. "Given a list of numbers, return the second-largest distinct value."
- 2Inputs and outputs, with Go types
[]intin. Out: anint— but what if there is no answer? In Go the honest signature is(int, bool), the same comma-ok shape as a map lookup, rather than a magic value like-1. - 3Constraints
How big is n? Can values be negative? Duplicates? Already sorted? These decide the algorithm (see the Big-O lesson below).
- 4Two examples by hand
One normal, one tricky. Work them out on paper. If you cannot do it by hand, you cannot code it.
- 5Edge cases
A nil or empty slice, one element, all values equal, negative numbers, values near the limits of
int.
package main
import "fmt"
// Restated: the second-largest distinct value in nums.
// Input: []int, may be nil or empty. Output: (value, ok); ok is false if there is none.
func secondLargest(nums []int) (int, bool) {
var first, second int
haveFirst, haveSecond := false, false
for _, n := range nums {
switch {
case !haveFirst || n > first:
if haveFirst {
second, haveSecond = first, true // old leader drops to second
}
first, haveFirst = n, true
case n < first && (!haveSecond || n > second):
second, haveSecond = n, true
}
}
return second, haveSecond
}
func main() {
fmt.Println(secondLargest([]int{4, 1, 7, 7, 3})) // normal, with a duplicate leader
fmt.Println(secondLargest([]int{5, 5, 5})) // all equal: no answer
fmt.Println(secondLargest(nil)) // empty
fmt.Println(secondLargest([]int{-2, -9})) // negatives
}4 true
0 false
0 false
-9 trueThe comments at the top are the reading step. The four calls in main are the examples and edge cases from that step. Starting first at 0 instead of tracking haveFirst would silently break the all-negative case.
