Dùng LINQ: Max(), Min(), OrderByDescending().Skip(1).First(), OrderBy().Skip(1).First().
Ví dụ minh họa
using System;
using System.Linq;
class Program
{
static void Main()
{
int[] numbers = { 99, 35, 26, 87 };
Console.WriteLine("Mảng: " + string.Join(", ", numbers));
// Max/Min
int max = numbers.Max();
int min = numbers.Min();
Console.WriteLine($"Max: {max}");
Console.WriteLine($"Min: {min}");
// Second Max/Min (cần distinct nếu có duplicate)
int secondMax = numbers.Distinct().OrderByDescending(x => x).Skip(1).FirstOrDefault();
int secondMin = numbers.Distinct().OrderBy(x => x).Skip(1).FirstOrDefault();
Console.WriteLine($"Second Max: {secondMax}");
Console.WriteLine($"Second Min: {secondMin}");
// Test với duplicate
int[] withDup = { 5, 5, 3, 3, 1 };
Console.WriteLine($"\nMảng có duplicate: {string.Join(", ", withDup)}");
Console.WriteLine($"Second Max (distinct): {withDup.Distinct().OrderByDescending(x => x).Skip(1).FirstOrDefault()}"); // 3
Console.WriteLine($"Second Min (distinct): {withDup.Distinct().OrderBy(x => x).Skip(1).FirstOrDefault()}"); // 3
}
}
Kết quả đầu ra
Mảng: 99, 35, 26, 87 Max: 99 Min: 26 Second Max: 87 Second Min: 35 Mảng có duplicate: 5, 5, 3, 3, 1 Second Max (distinct): 3 Second Min (distinct): 3
Lưu ý: Dùng Distinct() trước khi Skip/First để bỏ qua duplicate. FirstOrDefault() tránh exception khi mảng < 2 phần tử distinct.
Thuật toán O(n) single pass (không sort)
static (int Max, int Min, int SecondMax, int SecondMin) FindExtremes(int[] arr)
{
int max = int.MinValue, secondMax = int.MinValue;
int min = int.MaxValue, secondMin = int.MaxValue;
foreach (int x in arr)
{
// Max
if (x > max) { secondMax = max; max = x; }
else if (x > secondMax && x != max) secondMax = x;
// Min
if (x < min) { secondMin = min; min = x; }
else if (x < secondMin && x != min) secondMin = x;
}
return (max, min, secondMax, secondMin);
}