zl程序教程

您现在的位置是:首页 >  其他

当前栏目

力扣---54. 螺旋矩阵

2023-04-18 15:42:28 时间
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

示例 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]

提示:
    m == matrix.length
    n == matrix[i].length
    1 <= m, n <= 10
    -100 <= matrix[i][j] <= 100
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/spiral-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 

主要是边界考虑比较麻烦,难点也正在这里。

可以将循环分成四部分:从左向右,然后从上到下,然后从右到左,然后从下到上。

利用状态转换可以专注于当前状态,直到遇到边界后转移状态。

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> res = new ArrayList<>();
//        从左向右=0;从上到下=1;从右到左=2;从下到上=3;
        int direction = 0;
//        横坐标起始位置
        int start1 = 0;
//        纵坐标起始位置
        int start2 = 0;
//        横坐标终止位置
        int end1 = matrix[0].length;
//        纵坐标终止位置
        int end2 = matrix.length;
//        横坐标
        int p1 = 0;
//        纵坐标
        int p2 = 0;
//        计数器,统计添加过的数量
        int sum = end1 * end2;
        while (sum > 0) {
            res.add(matrix[p1][p2]);
            sum --;
            // 从左向右
            if (direction == 0) {
                p2 ++;
                // 边界
                if (p2 == end1) {
                    // 转移到从上到下
                    direction = 1;
                    // 左闭右开,需要退出边界
                    p2 --;
                    // 上边界向下移动一格
                    start1 ++;
                    // 横和竖会有一个重复的格子
                    p1 ++;
                }
                // 从上到下
            } else if (direction == 1) {
                p1 ++;
                // 边界
                if (p1 == end2) {
                    // 转移到从右向左
                    direction = 2;
                    // 退出边界
                    p1 --;
                    // 右边界向左移动一格
                    end1 --;
                    // 重复格子
                    p2 --;
                }
                // 从右向左
            } else if (direction == 2) {
                p2 --;
                // 边界
                if (p2 < start2) {
                    // 转移到从下到上
                    direction = 3;
                    // 退出边界
                    p2 ++;
                    // 下边界向上移动一格
                    end2 --;
                    // 重复格子
                    p1 --;
                }
                // 从下到上
            } else {
                p1 --;
                // 边界
                if (p1 < start1) {
                    // 转移到从左向右
                    direction = 0;
                    // 退出边界
                    p1 ++;
                    // 左边界向右移动一格
                    start2 ++;
                    // 重复格子
                    p2 ++;
                }
            }
        }
        return res;
    }
}

 

 还可以利用辅助数组来存储已经遍历过的点,以此来判断边界条件,这里直接放一个官解吧。

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> order = new ArrayList<Integer>();
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return order;
        }
        int rows = matrix.length, columns = matrix[0].length;
        boolean[][] visited = new boolean[rows][columns];
        int total = rows * columns;
        int row = 0, column = 0;
        int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        int directionIndex = 0;
        for (int i = 0; i < total; i++) {
            order.add(matrix[row][column]);
            visited[row][column] = true;
            int nextRow = row + directions[directionIndex][0], nextColumn = column + directions[directionIndex][1];
            if (nextRow < 0 || nextRow >= rows || nextColumn < 0 || nextColumn >= columns || visited[nextRow][nextColumn]) {
                directionIndex = (directionIndex + 1) % 4;
            }
            row += directions[directionIndex][0];
            column += directions[directionIndex][1];
        }
        return order;
    }
}


作者:LeetCode-Solution
链接:https://leetcode.cn/problems/spiral-matrix/solution/luo-xuan-ju-zhen-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。