🔥 Zapisy zamknięte, ale możesz pobrać Roadmapę .NET i dołączyć do listy oczekujących — Pobierz i dołącz do Listy VIP →

Znajdź minimum i maksimum — Zadanie rekrutacyjne #6

Czego szuka rekruter: obsługa pustej kolekcji, LINQ vs manual, czytelność
Poziom: Junior


Zadanie

Napisz funkcję, która w tablicy liczb całkowitych znajdzie najmniejszą i największą wartość. Nie używaj Math.Min/Math.Max ani LINQ (chyba że jako alternatywę).


Czego szuka rekruter

To zadanie o walidacji wejścia i wzorcu zwracania wyników. Rekruter patrzy na:

  • Co się stanie dla pustej tablicy lub null
  • Jak kandydat zwraca dwa wyniki — tuple, out parametry, osobna klasa
  • Czy inicjalizuje min/max poprawnie (pułapka: inicjalizacja zerem!)

Najczęstszy błąd: int min = 0, max = 0 — dla tablicy [-5, -3, -1] zwróci max = 0, co jest błędem bo 0 nie ma w tablicy.


Edge cases

  • Pusta tablica — nie ma min/max, trzeba zgłosić błąd lub zwrócić null
  • Tablica z jednym elementem — min = max = ten element
  • Wszystkie elementy ujemne — min/max muszą być ujemne
  • Tablica: [int.MinValue, int.MaxValue]

❌ Częsty błąd — inicjalizacja zerem

// BŁĄD:
static (int min, int max) FindMinMax(int[] arr)
{
    int min = 0, max = 0;  // ← BŁĄD: dla [-5, -3, -1] zwróci max=0
    foreach (var n in arr)
    {
        if (n < min) min = n;
        if (n > max) max = n;
    }
    return (min, max);
}

✅ Poprawne rozwiązanie

static (int Min, int Max) FindMinMax(int[] arr)
{
    if (arr == null || arr.Length == 0)
        throw new ArgumentException("Tablica nie może być pusta.", nameof(arr));
    
    int min = arr[0];
    int max = arr[0];
    
    for (int i = 1; i < arr.Length; i++)
    {
        if (arr[i] < min) min = arr[i];
        if (arr[i] > max) max = arr[i];
    }
    
    return (min, max);
}

// Użycie:
var (min, max) = FindMinMax(new[] { 5, 2, 8, 1, 9, 3 });
Console.WriteLine($"Min: {min}, Max: {max}");  // Min: 1, Max: 9

Inicjalizacja min = max = arr[0] jest kluczowa — zaczynamy od pierwszego elementu jako punktu odniesienia.


Alternatywa — LINQ (jedna linia, ale dwa przejścia)

static (int Min, int Max) FindMinMaxLinq(int[] arr)
{
    if (arr == null || arr.Length == 0)
        throw new ArgumentException("Tablica nie może być pusta.");
    
    return (arr.Min(), arr.Max());
}

Wadą jest podwójne przejście przez tablicę. Dla dużych danych lepsze jest jedno przejście z ręcznym porównaniem.


Wersja zwracająca null zamiast rzucania wyjątku

static (int Min, int Max)? TryFindMinMax(int[] arr)
{
    if (arr == null || arr.Length == 0)
        return null;
    
    int min = arr[0], max = arr[0];
    for (int i = 1; i < arr.Length; i++)
    {
        if (arr[i] < min) min = arr[i];
        if (arr[i] > max) max = arr[i];
    }
    return (min, max);
}

Testy jednostkowe

[Fact]
public void FindMinMax_TypicalArray_ReturnsCorrectResult()
{
    var (min, max) = FindMinMax(new[] { 5, 2, 8, 1, 9, 3 });
    Assert.Equal(1, min);
    Assert.Equal(9, max);
}

[Fact]
public void FindMinMax_AllNegative_ReturnsCorrectResult()
{
    var (min, max) = FindMinMax(new[] { -5, -3, -10, -1 });
    Assert.Equal(-10, min);
    Assert.Equal(-1, max);
}

[Fact]
public void FindMinMax_SingleElement_ReturnsSameForBoth()
{
    var (min, max) = FindMinMax(new[] { 42 });
    Assert.Equal(42, min);
    Assert.Equal(42, max);
}

[Fact]
public void FindMinMax_EmptyArray_ThrowsArgumentException()
{
    Assert.Throws<ArgumentException>(() => FindMinMax(Array.Empty<int>()));
}

Co powiedzieć na rozmowie

“Inicjalizuję min i max pierwszym elementem tablicy, nie zerem — gdybym użył zera, dla tablic z samymi wartościami ujemnymi zwróciłbym nieprawidłowy wynik. Dla pustej tablicy rzucam ArgumentException bo min/max z pustego zbioru jest matematycznie nieokreślone.”


Podsumowanie

Kluczowe: inicjalizacja pierwszym elementem tablicy, nie 0. Edge case pustej tablicy to obowiązek. LINQ jest wygodny ale przechodzi tablicę dwukrotnie — warto o tym wspomnieć.

👨‍💻
Mariusz Jurczenko
Senior .NET Developer · 10+ lat doświadczenia komercyjnego

Programista .NET z doświadczeniem komercyjnym w firmach takich jak COIG, Kamsoft czy Etisoft Smart Solutions. Twórca kursów, z których skorzystało już ponad 11 000 osób w Strefie Kursów i ponad 1 000 kursantów na dev-hobby.pl.

Specjalizacja: Clean Code, Clean Architecture i uczenie programowania tak, żeby dało się je naprawdę zrozumieć — nie wykuć.

1 comment

Dodaj komentarz

czytanie to początek

Zamień wiedzę w umiejętności

Pobierz darmową Roadmapę .NET i ułóż takie tematy jak ten w spójną ścieżkę do pierwszej pracy.

Pobieram roadmapę →