Start learning free

LESSON 86 OF 347 · CONDITIONAL STATEMENTS - CHALLENGES

Second Largest Value in C#: Middle of Three with Math.Min/Max

Practice Read the full explanation

Given 3 integers, return the second largest number.

Example 1:

Input: A = 7, B = 3, C = 9
Output: 7

Example 2:

Input: A = 12, B = 8, C = 3
Output: 8

Note:

Your algorithm should run in O(1) time and use O(1) extra space.


Hints:

There are three candidates to the solution: A, B and C. We should try out each of them until we find the correct one. How can we check if A is the solution? What should happen for A to be the second largest value?

A is the second largest value if min(B, C) <= A and A <= max(B, C). We can write an if statement checking these conditions and if they hold, return A:
if A >= min(B, C) and A <= max(B, C):
	return A
What if the conditions don't hold and A is not the solution? What should we do next?

We should test B. Similarly, B is the second largest value if min(A, C) <= B and B <= max(A, C). We can write an if statement checking these conditions and if they hold, return B.
if A >= min(B, C) and A <= max(B, C):
	return A
if B >= min(A, C) and B <= max(A, C):
	return B
What if not even B is the solution?

Then, it's clear that C is the solution, so we should return C. We don't even need to check the conditions anymore:
if A >= min(B, C) and A <= max(B, C):
	return A
if B >= min(A, C) and B <= max(A, C):
	return B
return C

STEP 1 OF 3
    Ctrl + Enter to check

    C# · CONDITIONAL STATEMENTS - CHALLENGES

    Second Largest Value in C#, explained

    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

    1. Test A. If Math.Min(B, C) <= A and A <= Math.Max(B, C), return A.
    2. Test B. Do the same with A and C as the other two numbers, and return B when the test passes.
    3. Return C. If neither A nor B is in the middle, C must 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.Min and Math.Max. These are static methods of the Math class in the System namespace. 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 around A, as in low <= A && A <= high, is how C# expresses a range check, because a chain like low <= A <= high isn'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. For 5, 5, 9, the test for A passes (5 <= 5 and 5 <= 9), and the method returns 5. For 5, 5, 5, it returns 5. Using strict < would break these cases and could fall through to the wrong answer.
    • Largest or smallest number. If A is the largest, A <= Math.Max(B, C) fails and the method moves on. The same happens when A is 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) gives 7.
    • SecondLargest(12, 8, 3) gives 8.
    • SecondLargest(1, 2, 3) gives 2.
    • SecondLargest(5, 5, 9) gives 5.
    • SecondLargest(5, 5, 5) gives 5.
    Keep going with C#About 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free