Problem overview
The method secondLargest of class Solution receives three integers, A, B and C, and returns the one in the middle: the second largest. In the first example, A = 7, B = 3, C = 9. The largest is 9, the smallest is 3, so the answer is 7. In the second, A = 12, B = 8, C = 3 gives 8.
The note asks for O(1) time and O(1) extra space. With a fixed number of inputs, that means a few comparisons and no collections.
Approach: test each candidate
The answer is always one of the three inputs, so check them one at a time. A number is the second largest when it sits between the other two: it is at least as big as the smaller of them and at most as big as the larger. For A that reads math.min(B, C) <= A && A <= math.max(B, C).
Sorting the three numbers and picking the middle one would also work, but it builds a collection for no good reason. Three comparisons are simpler and need no extra memory.
You only need to test two candidates. If neither A nor B is in the middle, the middle one must be C, so the last case needs no condition.
Step by step
- Test
A. Compute the smaller and the larger ofBandCwithmath.minandmath.max. IfAlies between them, return it. - Test
B. Do the same withAandCas the other two numbers. IfBlies between them, return it. - Return
C. The first two tests failed, soCis the middle value.
The solution in Scala
class Solution {
def secondLargest(A: Int, B: Int, C: Int): Int = {
if (math.min(B, C) <= A && A <= math.max(B, C)) {
return A
}
if (math.min(A, C) <= B && B <= math.max(A, C)) {
return B
}
return C
}
}
The Scala details worth knowing:
math.minandmath.max. They live in thescala.mathpackage, which is available asmathwithout an import. They work onIntvalues and return anInt.- Explicit
return. In Scala the last expression of a block is its value, so many programs leave outreturn. This solution uses it to leave early, which is legal in a method with a declared result type (: Int). The same method could be written as anif/else if/elsechain whose branches are justA,BandC. &&. Both comparisons must hold. It stops at the first one that is false.Intparameters. Parameters arevals: you can read them but not reassign them.
Complexity
Time: O(1). The method makes at most four min / max calls and four comparisons, whatever the values are.
Space: O(1). It creates no arrays or lists, only the values it returns.
Edge cases and common mistakes
- Ties. Duplicates are why the comparisons use
<=and not<. With(5, 5, 5)the method returns 5. With(4, 9, 9)it returns 9: the second largest is counted by position, so a repeated maximum is its own second largest. With(9, 9, 4)it also returns 9. - Strict comparisons. With
<in place of<=, a tie makes both tests fail, and the method wrongly falls through toC. For(9, 9, 4)it would return 4 instead of 9. - Mixing up the pairs. The test for
AusesBandC, the test forBusesAandC. Putting the candidate inside its ownminormaxmakes the test always true. - Returning the middle by order. The answer depends on the values, not on which argument is in the middle position. For
(1, 2, 3),(3, 2, 1)and(2, 3, 1)the result is 2 every time.
Testing
(7, 3, 9)gives7.(12, 8, 3)gives8.(1, 2, 3)gives2.(3, 2, 1)gives2.(5, 5, 5)gives5.(9, 9, 4)gives9.
