using System;
using System.Linq;
class Program
{
/// <summary>
/// Finds the N smallest values in a 2D matrix using a LINQ flatten-and-sort approach.
/// </summary>
/// <param name="matrix">The 2D input array of integers.</param>
/// <param name="n">The number of smallest elements to retrieve.</param>
/// <returns>An array containing the N smallest elements in ascending order.</returns>
public static int[] FindNSmallestLinq(int[,] matrix, int n)
{
// Guard clauses for null, empty array, or invalid element count
if (matrix == null || matrix.Length == 0 || n <= 0) {
return Array.Empty<int>();
}
// Cast converts the multidimensional array (int[,]) into an IEnumerable<int> sequence,
// effectively flattening it without manual looping. OrderBy handles sorting,
// Take selects the first N elements, and ToArray materializes the final result.
return matrix.Cast<int>()
.OrderBy(x => x)
.Take(n)
.ToArray();
}
/// <summary>
/// Alternative high-performance implementation using Array.Sort.
/// Flattens the array into memory and sorts in-place using IntroSort.
/// </summary>
/// <param name="matrix">The 2D input array of integers.</param>
/// <param name="n">The number of smallest elements to retrieve.</param>
/// <returns>An array containing the N smallest elements in ascending order.</returns>
public static int[] FindNSmallestFast(int[,] matrix, int n)
{
if (matrix == null || matrix.Length == 0 || n <= 0) {
return Array.Empty<int>();
}
// Allocate a 1D target buffer sized for all matrix elements
int totalElements = matrix.Length;
int[] flatArray = new int[totalElements];
// Buffer.BlockCopy offers fast raw memory block copying to flatten 2D rectangular arrays
Buffer.BlockCopy(matrix, 0, flatArray, 0, totalElements * sizeof(int));
// Sort the flattened buffer in-place
Array.Sort(flatArray);
// Slice out the first N values using modern C# range/span syntax
int targetCount = Math.Min(n, totalElements);
return flatArray[..targetCount];
}
public static void Main()
{
// Sample 4x4 matrix initialization
int[,] grid = {
{ 42, 12, 85, 3 },
{ 7, 99, 15, 23 },
{ 64, 1, 18, 30 },
{ 3, 55, 11, 90 }
};
Console.WriteLine("Input Matrix:");
for (int r = 0; r < grid.GetLength(0); r++)
{
Console.Write(" [ ");
for (int c = 0; c < grid.GetLength(1); c++) {
Console.Write($"{grid[r, c],3}");
if (c < grid.GetLength(1) - 1) Console.Write(",");
}
Console.WriteLine(" ]");
}
Console.WriteLine();
int count = 5;
Console.WriteLine($"Finding the {count} smallest values (LINQ):");
int[] smallestValues = FindNSmallestLinq(grid, count);
Console.WriteLine($"[{string.Join(", ", smallestValues)}]");
}
}
/*
run:
Input Matrix:
[ 42, 12, 85, 3 ]
[ 7, 99, 15, 23 ]
[ 64, 1, 18, 30 ]
[ 3, 55, 11, 90 ]
Finding the 5 smallest values (LINQ):
[1, 3, 3, 7, 11]
*/