查看原文
其他

436,剑指 Offer-顺时针打印矩阵

山大王wld 数据结构和算法 2022-05-01

All over the place was six pence, but he looked up at the moon. 

满地都是六便士,他却抬头看见了月亮。

问题描述



输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。


示例 1:

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]

输出:[1,2,3,6,9,8,7,4,5]

示例 2:

输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]

输出:[1,2,3,4,8,12,11,10,9,5,6,7]


限制:

  • 0 <= matrix.length <= 100

  • 0 <= matrix[i].length <= 100


问题分析



逆时针打印,也就是下面这张图这样

代码没什么难度,主要是在打印的时候做一些边界的判断,看下代码

1public int[] spiralOrder(int[][] matrix) {
2    if (matrix == null || matrix.length == 0)
3        return new int[0];
4    int m = matrix.length, n = matrix[0].length;
5    int[] res = new int[m * n];
6    int up = 0, down = m - 1, left = 0, right = n - 1, index = 0;
7    while (true) {
8        // 上面行,从左往右打印(行不变,改变列的下标)
9        for (int col = left; col <= right; col++)
10            res[index++] = matrix[up][col];
11        if (++up >
 down)
12            break;
13
14        // 右边列,从上往下打印(列不变,改变行的下标)
15        for (int row = up; row <= down; row++)
16            res[index++] = matrix[row][right];
17        if (--right < left)
18            break;
19
20        // 下面行,从右往左打印(行不变,改变列的下标)
21        for (int col = right; col >
= left; col--)
22            res[index++] = matrix[down][col];
23        if (--down < up)
24            break;
25
26        // 左边列,从下往上打印(列不变,改变行的下标)
27        for (int row = down; row >
= up; row--)
28            res[index++] = matrix[row][left];
29        if (++left > right)
30            break;
31    }
32    return res;
33}


再来看一种方式,就是每次打印的时候上面一行和下面一行都是完整打印,左边一列和右边一列打印的值是夹在上下两行之间的,打印一圈之后,再缩小圈的范围。和上面有一点点区别,但原理还是没变。

1public int[] spiralOrder(int[][] matrix) {
2    if (matrix == null || matrix.length == 0)
3        return new int[0];
4    int n = matrix.length, m = matrix[0].length;
5    int[] res = new int[m * n];
6    int up = 0, down = n - 1;
7    int left = 0, right = m - 1;
8    int total = m * n;
9    int index = 0;
10    while (index < total) {
11        //上面,从左往右打印
12        for (int j = left; j <= right && index < total; j++)
13            res[index++] = matrix[up][j];
14        //右边,从上往下打印(注意这里i的取值范围)
15        for (int i = up + 1; i <= down - 1 && index < total; i++)
16            res[index++] = matrix[i][right];
17        //下边,从右往左打印
18        for (int j = right; j >= left && index < total; j--)
19            res[index++] = matrix[down][j];
20        //左边,从下往上打印(注意这里i的取值范围)
21        for (int i = down - 1; i >= up + 1 && index < total; i--)
22            res[index++] = matrix[i][left];
23        left++;
24        right--;
25        up++;
26        down--;
27    }
28    return res;
29}


总结



难度不大,控制好边界条件沿着上右下左的方向打印就行了。



420,剑指 Offer-回溯算法解矩阵中的路径

419,剑指 Offer-旋转数组的最小数字

406,剑指 Offer-二维数组中的查找

350,有序矩阵中第K小的元素


长按上图,识别图中二维码之后即可关注。


如果觉得有用就点个"赞"吧

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存