LeetCode 867. 转置矩阵
题目描述


题意分析
转置将原矩阵的每一行变成结果中的一列:原来的 $m$ 行 $n$ 列,变成 $n$ 行 $m$ 列。元素值保持不变,只交换行下标和列下标,题目要求返回转置后的矩阵。
解法:直接转置
核心思路
[!blue]
原矩阵位置
(i, j)的元素,转置后应该放在结果位置(j, i),直接执行res[j][i] = matrix[i][j]。由于j的范围是0到n - 1,结果必须有n行;每行用i访问,又必须有m列。每个源坐标都对应唯一的目标坐标,反过来交换一次也能找回原坐标,所以遍历原矩阵一次就能填满结果,不会遗漏或重复覆盖。使用新矩阵后,读写彼此独立,方阵和非方阵都能采用相同循环。
解题步骤
- 读取原矩阵的行数
m和列数n,分配n行m列的结果矩阵。- Go 的二维切片还需要逐行分配内部长度为
m的切片,才能通过下标写入。- 遍历
0 <= i < m、0 <= j < n,将matrix[i][j]写入res[j][i],最后返回结果。单行转成单列、单列转成单行,也不需要特殊分支。
代码实现
class Solution {
public int[][] transpose(int[][] matrix) {
int m = matrix.length;
int n = matrix[0].length;
// 转置后行数来自原列数,列数来自原行数
int[][] res = new int[n][m];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
res[j][i] = matrix[i][j];
}
}
return res;
}
}
func transpose(matrix [][]int) [][]int {
m := len(matrix)
n := len(matrix[0])
// 转置后行数来自原列数,列数来自原行数
res := make([][]int, n)
for i := 0; i < n; i++ {
// 逐行分配原行数个元素,才能写入转置坐标
res[i] = make([]int, m)
}
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
res[j][i] = matrix[i][j]
}
}
return res
}
复杂度分析
- 时间复杂度:$O(mn)$,每个元素一次读写。
- 空间复杂度:输出 $O(mn)$,其余辅助空间 $O(1)$。
关键点总结
[!green]
- 结果形状与下标同时交换。
- 转置不同于旋转,也不同于按新形状简单重排。
易错点总结
[!yellow]
- 结果仍按原维度分配,会在非方阵上越界。
- Go 只分配外层就写元素,会访问未分配的行。
- 按原顺序拍平后重新分组,并没有实现转置坐标映射。
相似题目
| 题目 | 难度 | 关联与区别 |
|---|---|---|
| 48. 旋转图像 | 中等 | 顺时针旋转可拆成转置再按行反转,本题只交换行列坐标。 |
转载与许可
许可
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!