Problem overview
The method SecondLargest receives three integers, A, B and C, and returns the second largest of them, which is the middle value when the three are sorted. For A = 7, B = 3, C = 9, the sorted order is 3, 7, 9, so the answer is 7. For A = 12, B = 8, C = 3 the answer is 8.
The lesson asks for O(1) time and space. With only three numbers there is no need to sort anything: a few comparisons are enough.
Approach: test each candidate
The answer has to be one of the three numbers, so check them in turn. A number is the middle value exactly when it lies between the other two, which means it is at least the smaller of the other two and at most the larger of the other two.
For A, the test is Math.Min(B, C) <= A && A <= Math.Max(B, C). The same test works for B, with A and C as the other two. If neither A nor B passes, the answer is C, and no third test is needed.
For A = 7, B = 3, C = 9: the smaller of B and C is 3 and the larger is 9. Since 3 <= 7 and 7 <= 9, A is returned.
Now take A = 12, B = 8, C = 3. For A, the other two are 8 and 3, so the range is 3 to 8, and 12 is outside it. The test fails. For B, the other two are 12 and 3, so the range is 3 to 12, and 8 is inside it. The method returns 8.
Step by step
- Test
A. IfMath.Min(B, C) <= AandA <= Math.Max(B, C), returnA. - Test
B. Do the same withAandCas the other two numbers, and returnBwhen the test passes. - Return
C. If neitherAnorBis in the middle,Cmust be.
The solution in C#
class Solution {
public int SecondLargest(int A, int B, int C) {
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;
}
}
Some C# details:
Math.MinandMath.Max. These are static methods of theMathclass in theSystemnamespace. They take two numbers and return the smaller or the larger one. The names start with capital letters.- Combining the two tests.
&&requires both sides to be true. Writing the bounds aroundA, as inlow <= A && A <= high, is how C# expresses a range check, because a chain likelow <= A <= highisn't valid. - Early returns. When the first test passes, the method returns at once and the other tests don't run.
- The last line has no condition. The compiler only needs every path to return, and the final
return C;covers it.
Complexity
Time: O(1). The method makes at most two range checks, each using two Math calls and two comparisons. The count doesn't depend on the values.
Space: O(1). No extra storage is used.
Edge cases and common mistakes
- Equal values. The tests use
<=, so ties work. For5, 5, 9, the test forApasses (5 <= 5and5 <= 9), and the method returns 5. For5, 5, 5, it returns 5. Using strict<would break these cases and could fall through to the wrong answer. - Largest or smallest number. If
Ais the largest,A <= Math.Max(B, C)fails and the method moves on. The same happens whenAis the smallest, through the first half of the test. - Negative numbers. The comparisons work the same for negatives. For
-2, -9, -5, the answer is-5. - Returning the middle position. The method returns a value, not an index or position.
- Sorting by mistake. Putting the numbers into an array and sorting also works, but it needs extra storage and is more than this lesson asks for.
Testing
SecondLargest(7, 3, 9)gives7.SecondLargest(12, 8, 3)gives8.SecondLargest(1, 2, 3)gives2.SecondLargest(5, 5, 9)gives5.SecondLargest(5, 5, 5)gives5.