将矩阵按对角线排序Java
文章发布较早,内容可能过时,阅读注意甄别。
# 题目
矩阵对角线 是一条从矩阵最上面行或者最左侧列中的某个元素开始的对角线,沿右下方向一直到矩阵末尾的元素。例如,矩阵 mat 有 6 行 3 列,从 mat[2][0] 开始的 矩阵对角线 将会经过 mat[2][0]、mat[3][1] 和 mat[4][2] 。
给你一个 m * n 的整数矩阵 mat ,请你将同一条 矩阵对角线 上的元素按升序排序后,返回排好序的矩阵。
示例 1:
输入:mat = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]
输出:[[1,1,1,1],[1,2,2,2],[1,2,3,3]]
示例 2:
输入:mat = [[11,25,66,1,69,7],[23,55,17,45,15,52],[75,31,36,44,58,8],[22,27,33,25,68,4],[84,28,14,11,5,50]]
输出:[[5,17,4,1,52,7],[11,11,25,45,8,69],[14,23,25,44,58,15],[22,27,31,36,50,66],[84,28,75,33,55,68]]
提示:
- m == mat.length
- n == mat[i].length
- 1 <= m, n <= 100
- 1 <= mat[i][j] <= 100
# 思路
堆排序 O(nlogn)
# 解法
class Solution {
public int[][] diagonalSort(int[][] mat) {
int n = mat.length, m = mat[0].length;
for (int i = 0; i < n; i++) {
int size = Math.min(n - i, m);
for (int k = size - 1; k >= 0; k--) {// 原地堆化 O(n)
heapify1(mat, size, i + k, k);
}
for (int k = size - 1; k >= 0; k--) {// 堆排序 O(nlogn)
swap(mat, i, 0, i + k, k);
heapify1(mat, k, i, 0);
}
}
for (int j = 1; j < m; j++) {
int size = Math.min(n, m - j);
for (int k = size - 1; k >= 0; k--) {// 原地堆化 O(n)
heapify2(mat, size, k, j + k);
}
for (int k = size - 1; k >= 0; k--) {// 堆排序 O(nlogn)
swap(mat, 0, j, k, j + k);
heapify2(mat, k, 0, j);
}
}
return mat;
}
public void heapify1(int[][] mat, int size, int i, int j) {
int lx = i + j + 1, ly = j * 2 + 1;
while (ly < size) {
int by = ly + 1 < size && mat[lx + 1][ly + 1] > mat[lx][ly] ? ly + 1 : ly, bx = by == ly ? lx : lx + 1;
by = mat[bx][by] > mat[i][j] ? by : j;
bx = by == j ? i : bx;
if (by == j) {
break;
}
swap(mat, i, j, bx, by);
i = bx;
j = by;
lx = i + j + 1;
ly = j * 2 + 1;
}
}
public void heapify2(int[][] mat, int size, int i, int j) {
int lx = i * 2 + 1, ly = j + i + 1;
while (lx < size) {
int bx = lx + 1 < size && mat[lx + 1][ly + 1] > mat[lx][ly] ? lx + 1 : lx, by = bx == lx ? ly : ly + 1;
bx = mat[bx][by] > mat[i][j] ? bx : i;
by = bx == i ? j : by;
if (bx == i) {
break;
}
swap(mat, i, j, bx, by);
i = bx;
j = by;
lx = i * 2 + 1;
ly = j + i + 1;
}
}
public void swap(int[][] mat, int x1, int y1, int x2, int y2) {
int t = mat[x1][y1];
mat[x1][y1] = mat[x2][y2];
mat[x2][y2] = t;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# 总结
- 分析出几种情况,然后分别对各个情况实现