LeetCode螺旋矩阵 54. 59

54. 螺旋矩阵

题目描述:给你一个 m 行 n 列的矩阵 matrix ,请按照顺时针螺旋顺序,返回矩阵中的所有元素。

题解:模拟即可。两种模拟方式:

  1. 直接模拟
  2. 按层模拟(转圈遍历)

直接模拟:设置方向数组,以及当前方向,以及4个方向的边界,每次更新坐标[i,j],若更新后越界,则切换到下一个方向

class Solution {

    public List<Integer> spiralOrder(int[][] matrix) {
        int n = matrix.length, m = matrix[0].length;
        int[][] direction = new int[][]{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        int directionIndex = 0; // 初始向右
        List<Integer> ans = new ArrayList<>();
        // 四个边界
        int leftBoundary = 0, rightBoundary = m - 1, upBoundary = 0, bottomBoundary = n - 1;
        // 当前坐标
        int i = 0, j = 0;
        while (i >= upBoundary && i <= bottomBoundary && j >= leftBoundary && j <= rightBoundary) {
            ans.add(matrix[i][j]);
            int ni = i + direction[directionIndex][0];
            int nj = j + direction[directionIndex][1];
            if (ni < upBoundary || ni > bottomBoundary || nj < leftBoundary || nj > rightBoundary) {
                // 需要换方向了, 要更新边界
                if (directionIndex == 0) upBoundary++;
                else if (directionIndex == 1) rightBoundary--;
                else if (directionIndex == 2) bottomBoundary--;
                else leftBoundary++;
				// 切换到下一个方向
                directionIndex = (directionIndex + 1) % 4;
                ni = i + direction[directionIndex][0];
                nj = j + direction[directionIndex][1];
            }
            i = ni;
            j = nj;
        }
        return ans;
    }
}

按层模拟

class Solution {

    public List<Integer> spiralOrder(int[][] matrix) {
        int n = matrix.length, m = matrix[0].length;
        int total = n * m; // 总的数量
        int top = 0, bottom = n - 1, left = 0, right = m - 1;
        List<Integer> ans = new ArrayList<>();
        int i = 0; // 计数
        while (i < total) {
            for (int j = left; j <= right && i < total; j++) {
                ans.add(matrix[top][j]);
                i++;
            }
            top++;
            for (int j = top; j <= bottom && i < total; j++) {
                ans.add(matrix[j][right]);
                i++;
            }
            right--;
            for (int j = right; j >= left && i < total; j--) {
                ans.add(matrix[bottom][j]);
                i++;
            }
            bottom--;
            for (int j = bottom; j >= top && i <total; j--) {
                ans.add(matrix[j][left]);
                i++;
            }
            left++;
        }
        return ans;
    }
}

59. 螺旋矩阵II

题目描述:给你一个正整数 n ,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

题解:和54类似,一个是遍历输出,一个是遍历填入。同样两种方式

  1. 直接模拟
  2. 按层模拟

直接模拟

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] ans = new int[n][n];
        int i = 0, j = 0;
        int top = 0, bottom = n - 1, left = 0, right = n - 1;
        int[][] d = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        int di = 0; // direction 
        int idx = 1; // 填充的元素
        while (i >= top && i <= bottom && j >= left && left <= right) {
            ans[i][j] = idx++; // 填充到当前位置
            int ni = i + d[di][0];
            int nj = j + d[di][1];
            if (ni < top || ni > bottom || nj < left || nj > right) {
                
                if (di == 0) top++;
                else if (di == 1) right--;
                else if (di == 2) bottom--;
                else left++;

                di = (di + 1) % 4;
                ni = i + d[di][0];
                nj = j + d[di][1];
            }
            i = ni;
            j = nj;
        }
        return ans;
    }
}

按层模拟(一圈一圈填入):

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] ans = new int[n][n];
        int total = n * n;
        int idx = 1;
        int top = 0, bottom = n - 1, left = 0, right = n - 1;
        while (idx <= total) {
            for (int i = left; i <= right && idx <= total; i++) ans[top][i] = idx++;
            top++;
            for (int i = top; i <= bottom && idx <= total; i++) ans[i][right] = idx++;
            right--;
            for (int i = right; i >= left && idx <= total; i--) ans[bottom][i] = idx++;
            bottom--;
            for (int i = bottom; i >= top && idx <= total; i--) ans[i][left] = idx++;
            left++; 
        }
        return ans;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值