JavaInterview JavaInterview
首页
指南
分类
标签
归档
  • CSDN (opens new window)
  • 文档集合 (opens new window)
  • 系统架构 (opens new window)
  • 微信号 (opens new window)
  • 公众号 (opens new window)

『Java面试+Java学习』
首页
指南
分类
标签
归档
  • CSDN (opens new window)
  • 文档集合 (opens new window)
  • 系统架构 (opens new window)
  • 微信号 (opens new window)
  • 公众号 (opens new window)
  • 指南
  • 简历

  • Java

  • 面试

  • 算法

  • algorithm
  • leetcode
JavaInterview.cn
2024-09-28
目录

将矩阵按对角线排序Java

文章发布较早,内容可能过时,阅读注意甄别。

# 题目

矩阵对角线 是一条从矩阵最上面行或者最左侧列中的某个元素开始的对角线,沿右下方向一直到矩阵末尾的元素。例如,矩阵 mat 有 6 行 3 列,从 mat[2][0] 开始的 矩阵对角线 将会经过 mat[2][0]、mat[3][1] 和 mat[4][2] 。

给你一个 m * n 的整数矩阵 mat ,请你将同一条 矩阵对角线 上的元素按升序排序后,返回排好序的矩阵。

示例 1:

1482_example_1_2.png

输入: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

# 总结

  • 分析出几种情况,然后分别对各个情况实现
微信 支付宝
#Java
最近更新
01
1686. 石子游戏VI Java
08-18
02
1688. 比赛中的配对次数 Java
08-18
03
1687. 从仓库到码头运输箱子 Java
08-18
更多文章>
Theme by Vdoing | Copyright © 2019-2025 JavaInterview.cn
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式