螺旋矩阵

思路

螺旋矩阵1,2: 1) 按顺时针方向模拟 定义方向=> 初始方向递进, 遇到转折点变换方向, 遍历全部元素 2) 按层模拟: 确定层数 => 处理层 => 处理非圈

题解

// [54. 螺旋矩阵](https://leetcode-cn.com/problems/spiral-matrix/)
// 这样模拟更简洁, 更加不容易出错. 但是增加了空间复杂度used数组
class Solution1 {
    public List<Integer> spiralOrder(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        int[][] direction = new int[][]{{0, 1}, {1, 0}, {0, - 1}, {-1, 0}}; // 四个方向的循环
        int dIndex = 0; // 方向索引,默认是direction[0] 也就是从左到右
        int[][] used = new int[m][n]; // 记录遍历过位置, 用于判断是否转变方向
        List<Integer> result = new LinkedList<>();
        // 1. 遍历全部元素
        int r = 0;
        int c = 0;
        for (int i = 0; i < m * n; i++) {
            // 2. 访问当前元素
            result.add(matrix[r][c]);
            used[r][c] = 1;
            // 3. 转变方向(判断到达转折点)
            int nextR = r + direction[dIndex][0], nextC = c + direction[dIndex][1];
            if (nextR < 0 || nextR >= m || nextC < 0 || nextC >= n || used[nextR][nextC] == 1) dIndex = (dIndex + 1) % 4;
            // 跟新step
            r = r + direction[dIndex][0];
            c = c + direction[dIndex][1];
        }
        return result;
    }
}
// 模拟循环过程, 1)方形: 奇数, 偶数, 2)非方形: 取决于短边 => 定义圈数量
class Solution2 {
    public List<Integer> spiralOrder(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        int loop = Math.min(m, n) / 2;
        List<Integer> result = new LinkedList<>();
        // 1. 对圈进行处理: 区间保持[), loop = 2
        for (int k = 0; k < loop; k++) {
            // 左->右
            for (int j = k; j < k + n - 1 - 2 * k; j++) {
                result.add(matrix[k][j]);
            }
            // 上->下
            for (int i = k; i < k + m - 1 - 2 * k; i++) {
                result.add(matrix[i][k + n - 1 - 2 * k]);
            }
            // 右->左
            for (int j = n - 1 - k; j > k; j--) {
                result.add(matrix[m - 1 - k][j]);
            }
            // 下->上
            for (int i = m - 1 - k; i > k; i--) {
                result.add(matrix[i][k]);
            }
        }
        // 2. 非圈进行处理: i / 2,
        if (n == m && m % 2 != 0) result.add(matrix[m / 2][n / 2]);
        if (n > m && m % 2 != 0) {
            for (int j = loop; j < loop + n - m + 1; j++) result.add(matrix[loop][j]); // 往右走
        }
        if (n < m && n % 2 != 0){
            for (int i = loop; i < loop + m - n + 1; i++) result.add(matrix[i][loop]); // 往下走
        }
        // 3. 返回结果
        return result;
    }
}
posted @ 2022-02-18 23:07  -Rocky-  阅读(138)  评论(0编辑  收藏  举报