Transpose Matrix
Du erhältst eine Matrix aus Ganzzahlen als Liste von Zeilen: matrix[i][j] ist der Wert in Zeile i, Spalte j. Gib ihre Transponierte zurück: Der Wert in Zeile i, Spalte j wird in Zeile j, Spalte i verschoben, sodass jede Zeile zu einer Spalte wird. Die Matrix muss nicht quadratisch sein: Eine m × n-Matrix wird zu einer n × m-Matrix.
Funktion
- matrixinteger-2d-array
- die m × n-Matrix als Liste aus m Zeilen mit n Ganzzahlen
- Gibt zurückinteger-2d-array
- die n × m-Transponierte, als Liste aus n Zeilen mit m Ganzzahlen
Einschränkungen
1 ≤ m, n ≤ 1000, wobeim = matrix.lengthundn = matrix[i].lengthm × n ≤ 5000- Jede Zeile hat dieselbe Länge
n. -1000 ≤ matrix[i][j] ≤ 1000
Beispiele
- Eingabe
- matrix = [[1, 2, 3], [4, 5, 6]]
- Ausgabe
- [[1, 4], [2, 5], [3, 6]]
- Erklärung
- Die Zeile
[1, 2, 3]wird zur ersten Spalte und[4, 5, 6]zur zweiten. Zeilenweise gelesen lautet das Ergebnis[1, 4],[2, 5],[3, 6]: eine 3 × 2-Matrix.
- Eingabe
- matrix = [[1, 2], [3, 4]]
- Ausgabe
- [[1, 3], [2, 4]]
- Erklärung
- Die Diagonalwerte 1 und 4 bleiben an Ort und Stelle. Die beiden anderen tauschen ihre Plätze: 2 wandert von Zeile 0, Spalte 1 zu Zeile 1, Spalte 0, und 3 wandert in die andere Richtung.
Weiterführende Frage
Angenommen, die Matrix ist als ein flaches Array aus m × n Werten gespeichert, Zeile für Zeile. Kannst du eine nicht quadratische Matrix innerhalb dieses Arrays transponieren, ohne ein zweites Array?
Tipps
Öffne sie nacheinander. Jeder verrät ein bisschen mehr.
Wenn die Eingabe
mZeilen undnSpalten hat, wie viele Zeilen und Spalten hat die Antwort?Vergleiche, wo ein Wert vorher und nachher steht: Der Wert in Zeile
i, Spaltejbefindet sich anschließend in Zeilej, Spaltei.Erstelle ein Ergebnis mit
nZeilen und jeweilsmWerten. Durchlaufe dann jede Zelle der Eingabe und kopierematrix[i][j]nachresult[j][i].
Lösung
Beim Transponieren wird nichts berechnet: Der Wert an (i, j) wandert zu (j, i). Die Arbeit besteht in der Form. Das Ergebnis hat n Zeilen mit der Länge m, daher kann eine nicht quadratische Liste von Zeilen nicht direkt transponiert werden; erstelle eine neue Matrix mit vertauschten Dimensionen und fülle sie.
Lies die Matrix spaltenweise
Idee
Zeile j der Antwort ist Spalte j der Eingabe, von oben nach unten gelesen. Für [[1, 2, 3], [4, 5, 6]] enthält Spalte 0 erst 1, dann 4, also ist die erste Zeile der Antwort [1, 4].
Jeder Wert wird einmal gelesen und einmal geschrieben: Laufzeit O(m × n) und O(m × n) Speicherplatz für das Ergebnis. Beim Erstellen jeder neuen Zeile springst du über jede Eingabezeile, statt eine Zeile entlangzugehen. Das ist die langsamere Art, den Speicher zu durchlaufen.
Algorithmus
- Sei
mdie Anzahl der Zeilen undndie Länge einer Zeile. - Beginne für jede Spalte
jvon0bisn-1mit einer leeren Liste. - Füge
matrix[i][j]für jedesivon0bism-1hinzu. - Füge die Liste als Zeile
jzum Ergebnis hinzu und gib das Ergebnis nach der letzten Spalte zurück.
def transpose(matrix):
m, n = len(matrix), len(matrix[0])
result = []
for j in range(n):
# Column j, read top to bottom, becomes row j of the answer.
column = []
for i in range(m):
column.append(matrix[i][j])
result.append(column)
return resultFülle ein neues n × m-Raster, indem du jede Zelle spiegelst
Idee
Erstelle das n × m-Ergebnis vorab, lies dann die Eingabe in der gespeicherten Reihenfolge zeilenweise ein und setze jeden Wert an seine gespiegelte Adresse: result[j][i] = matrix[i][j]. Das ist korrekt, weil eine Transponierung genau diesen Tausch der Indizes darstellt, der einmal auf jede Zelle angewendet wird.
Jeder Wert wird einmal kopiert, daher beträgt die Laufzeit O(m × n), und das Raster benötigt O(m × n) Speicherplatz, den die Ausgabe ohnehin braucht. Das zeilenweise Lesen greift in der gespeicherten Reihenfolge auf den Speicher zu, und jede Ergebniszeile wird einmal mit ihrer endgültigen Größe angelegt.
Algorithmus
- Sei
mdie Anzahl der Zeilen undndie Länge einer Zeile. - Erstelle
resultmitnZeilen, die jeweilsmWerte enthalten. - Setze für jede Zeile
iund jede Spaltejder Eingaberesult[j][i] = matrix[i][j]. - Gib
resultzurück.
def transpose(matrix):
m, n = len(matrix), len(matrix[0])
# The answer has n rows of m values each.
result = [[0] * m for _ in range(n)]
for i in range(m):
for j in range(n):
result[j][i] = matrix[i][j]
return result
Stolperfallen und Grenzfälle
- Das Ergebnis mit der Form der Eingabe erstellen. Beim Beispiel mit 2 × 3 läuft
result[2][0]über das Ende hinaus: Das Ergebnis benötigtnZeilen der Längem. matrix[i][j]undmatrix[j][i]direkt vertauschen. Das funktioniert nur, wennm = n, und nur für Zellen mitj > i; eine Schleife über alle Zellen vertauscht jedes Paar zweimal und gibt die Matrix unverändert zurück.- In Python erstellt
[[0] * m] * nnVerweise auf dieselbe Liste, sodass das Schreiben in eine Zelle eine ganze Spalte verändert. Erstelle jede Zeile einzeln. - In C liest der Aufrufer
*returnSizeals Anzahl der Ergebniszeilen,n, und(*returnColumnSizes)[j]als Länge jeder Zeile,m.
Häufige Fragen3
Was ist die Transponierte einer Matrix?
Es ist die Matrix, die du erhältst, indem du Zeilen und Spalten vertauschst: Der Wert in Zeile i, Spalte j wandert in Zeile j, Spalte i. Eine 2 × 3-Matrix wird zu einer 3 × 2-Matrix, und zweimaliges Transponieren ergibt wieder die ursprüngliche Matrix.
Wie hoch ist die Zeitkomplexität beim Transponieren einer Matrix?
O(m × n): Jeder der m × n Werte wird einmal kopiert, und weniger ist nicht möglich, um das Ergebnis zu erzeugen. Die neue Matrix benötigt O(m × n) Speicherplatz, also so viel wie die Ausgabe selbst.
Kannst du eine Matrix direkt transponieren?
Bei einer quadratischen Matrix: Ja. Vertausche matrix[i][j] mit matrix[j][i] für jede Zelle oberhalb der Diagonalen, mit O(1) zusätzlichem Speicher. Eine nicht quadratische Matrix ändert ihre Form, daher brauchst du bei einer Liste von Zeilen eine neue Matrix.
Ähnliche Aufgaben
Aufgaben mit denselben Ideen. Wer zwei oder drei davon löst, behält das Muster.
def transpose(matrix):
# Schreibe hier den CodeTest #1
Test #2
Argument
matrix = [[1, 2, 3], [4, 5, 6]]
Erwartete Ausgabe
[[1, 4], [2, 5], [3, 6]]