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

Transpozycja tablicy — Zadanie rekrutacyjne #14

Czego szuka rekruter: macierze 2D, zamiana wierszy z kolumnami, in-place vs nowa tablica
Poziom: Junior / Mid


Zadanie

Napisz funkcję, która transponuje macierz (tablicę dwuwymiarową). Transpozycja zamienia wiersze z kolumnami: element [i][j] trafia na pozycję [j][i].

Wejście:          Wyjście:
1  2  3           1  4  7
4  5  6    →      2  5  8
7  8  9           3  6  9

Czego szuka rekruter

Rekruter sprawdza:

  • Czy kandydat rozumie indeksowanie tablicy 2D
  • Czy myśli o macierzach niekwadratowych (np. 3×2 → 2×3)
  • Czy wie że transpozycja in-place działa tylko dla macierzy kwadratowych
  • Jak iteruje przez elementy (dwie zagnieżdżone pętle)

Edge cases

  • Macierz kwadratowa (n×n) — można transponować in-place
  • Macierz prostokątna (m×n) — wymaga nowej tablicy o wymiarach n×m
  • Macierz 1×1 — wynik = wejście
  • null lub pusta macierz

✅ Rozwiązanie — nowa tablica (dla m×n)

static int[,] Transpose(int[,] matrix)
{
    if (matrix == null)
        throw new ArgumentNullException(nameof(matrix));
    
    int rows = matrix.GetLength(0);    // liczba wierszy
    int cols = matrix.GetLength(1);    // liczba kolumn
    
    // Wynikowa macierz ma odwrócone wymiary: cols×rows
    var result = new int[cols, rows];
    
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < cols; j++)
            result[j, i] = matrix[i, j];  // zamiana indeksów
    
    return result;
}

// Użycie:
int[,] matrix = {
    { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 9 }
};

var transposed = Transpose(matrix);
// transposed[0,0]=1, transposed[0,1]=4, transposed[0,2]=7
// transposed[1,0]=2, transposed[1,1]=5, transposed[1,2]=8
// transposed[2,0]=3, transposed[2,1]=6, transposed[2,2]=9

Transpozycja in-place — tylko dla macierzy kwadratowych

static void TransposeInPlace(int[,] matrix)
{
    int n = matrix.GetLength(0);
    if (n != matrix.GetLength(1))
        throw new ArgumentException("Transpozycja in-place wymaga macierzy kwadratowej.");
    
    for (int i = 0; i < n; i++)
        for (int j = i + 1; j < n; j++)  // j zaczyna od i+1 — nie zamieniaj dwa razy
            (matrix[i, j], matrix[j, i]) = (matrix[j, i], matrix[i, j]);
}

Pętla wewnętrzna zaczyna od j = i + 1 żeby każdą parę (i,j) zamienić tylko raz. Gdyby j zaczynał od 0 — zamienialibyśmy każdą parę dwa razy, co dałoby oryginalną macierz.


Wersja z tablicą postrzępioną (jagged array)

static int[][] TransposeJagged(int[][] matrix)
{
    if (matrix == null || matrix.Length == 0)
        return Array.Empty<int[]>();
    
    int rows = matrix.Length;
    int cols = matrix[0].Length;  // zakładamy prostokąt
    
    var result = new int[cols][];
    for (int j = 0; j < cols; j++)
    {
        result[j] = new int[rows];
        for (int i = 0; i < rows; i++)
            result[j][i] = matrix[i][j];
    }
    return result;
}

int[][] (jagged) vs int[,] (rectangular) — w C# to dwie różne struktury. Jagged array to “tablica tablic” i każdy wiersz może mieć inną długość. Rectangular (int[,]) jest jednolitym blokiem pamięci.


Testy jednostkowe

[Fact]
public void Transpose_SquareMatrix_SwapsRowsAndColumns()
{
    var matrix = new int[,] { { 1, 2 }, { 3, 4 } };
    var result = Transpose(matrix);
    
    Assert.Equal(1, result[0, 0]);
    Assert.Equal(3, result[0, 1]);
    Assert.Equal(2, result[1, 0]);
    Assert.Equal(4, result[1, 1]);
}

[Fact]
public void Transpose_RectangularMatrix_ChangesShape()
{
    var matrix = new int[,] { { 1, 2, 3 }, { 4, 5, 6 } };  // 2×3
    var result = Transpose(matrix);
    
    Assert.Equal(3, result.GetLength(0));  // 3×2
    Assert.Equal(2, result.GetLength(1));
    Assert.Equal(1, result[0, 0]);
    Assert.Equal(4, result[0, 1]);
    Assert.Equal(3, result[2, 0]);
    Assert.Equal(6, result[2, 1]);
}

[Fact]
public void TransposeInPlace_SwapsCorrectly()
{
    var matrix = new int[,] { { 1, 2 }, { 3, 4 } };
    TransposeInPlace(matrix);
    
    Assert.Equal(1, matrix[0, 0]);
    Assert.Equal(3, matrix[0, 1]);
    Assert.Equal(2, matrix[1, 0]);
    Assert.Equal(4, matrix[1, 1]);
}

Co powiedzieć na rozmowie

“Transpozycja macierzy m×n tworzy nową macierz n×m. Kluczowe: wynikowa tablica ma odwrócone wymiary. Transpozycja in-place działa tylko dla macierzy kwadratowych — dla prostokątnej potrzebujemy nowej pamięci. In-place musi iterować tylko nad ‘górnym trójkątem’ (j od i+1) żeby każdą parę zamienić raz.”


Podsumowanie

ScenariuszPodejście
Macierz kwadratowa, in-placeDwie pętle, j od i+1
Macierz prostokątnaNowa tablica o odwróconych wymiarach
int[,] vs int[][]Prostokąt vs jagged — różna składnia dostępu
👨‍💻
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ć.

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ę →