螺旋矩阵

独自空忆成欢 提交于 2020-03-12 04:10:49

问题描述:

给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。

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

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

问题分析:

旋转操作必存在方向的转变。对于一个二维数组(矩阵)而言,顺时针旋转只存在四次方向的改变(右下左上)。假设我们的初始方向是向右,当不能继续向右时,我们就要将方向改变为向下(因为是顺时针旋转),当不能继续向下前时,改变方向为向左,以此类推。。。
在这里,说明一下什么情况下我们就不能按照原方向访问元素。当我们找到的下一个坐标越界或者下一个坐标的元素已经被访问过,此时,我们就不能按照原方向访问了。
因此,我们需要一个标志数组,记录矩阵中的每一个元素是否被访问过。

代码实现:

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List ans = new ArrayList();
        if(matrix.length == 0)  return ans;
        int row = matrix.length, col = matrix[0].length;
        // 标志数组:true 表示被访问过,false 表示没被访问过
        boolean[][] seen = new boolean[row][col];
        // 改变方向时,行坐标的变化(下标为0,表示向右,按照右下左上的顺序)
        int[] dr = {0, 1, 0, -1};
        // 改变方向时,列坐标的变化
        int[] dc = {1, 0, -1, 0};
        int r = 0, c = 0, dir = 0;
        for (int i = 0; i < row * col; i++) {
            ans.add(matrix[r][c]);
            seen[r][c] = true;
            // 寻找下一个坐标
            int nextR = r + dr[dir];
            int nextC = c + dc[dir];
            // 如果下一个坐标可以访问,访问下一个坐标
            // 否则,改变方向,继续寻找下一个方向
            if (0 <= nextR && nextR < row && 0 <= nextC && nextC < col && !seen[nextR][nextC]){
                r = nextR;
                c = nextC;
            } else {
                dir = (dir + 1) % 4;
                r += dr[dir];
                c += dc[dir];
            }
        }
        return ans;
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!