0
点赞
收藏
分享

微信扫一扫

LeetCode(Java)经典题之螺旋矩阵(54、59)

陬者 2022-04-07 阅读 86

螺旋矩阵这名真的起的无比高大上,以至于我产生了畏难情绪,但当我点开题目的时候,就这????就这就这????

第59题:

所以思路就来了(因为我看了答案),这一个n*n的矩阵,当然需要用到二维数组来存储,所以定义一个二维数组来接收是必须的,而又如何做到题目所说的顺时针打印呢?

我们模拟一下打印的流程,首先从左往右打印第一行,接着从上往下打印最后一列,然后从右往左打印最后一行,最后从下往上打印第一列,如此重复下去。

注意到一个细节,第一行打印完的时候,相当于它“废掉”了,以后不会再打印它了。同样地,最后一列,最后一行,第一列,它们打印完的时候也就相当于废掉了,不会再用到它们了。

所以我们干脆咔咔定义四个指针(left、right、up、down),初始值分别为left = 0(指向第一列),right = n - 1(指向最后一列),up = 0(指向第一行),down = n - 1(指向最后一行),这样第一列打完的时候,可以让left++,实现废掉第一列,准备打印第二列的目的。同样地,right--,up++,down--,都是我们在进行完一次打印后需要做的。

想清楚这些之后,上代码:

public class question59 {
    public int[][] generateMatrix(int n) {
        int res[][] = new int[n][n];
        int left = 0,right = n - 1,up = 0,down = n - 1,index = 1;
        while (index <= n * n) {
            for (int i = left; i <= right; i++) {
                res[up][i] = index++;
            }
            up++;
            for (int i = up; i <= down; i++) {
                res[i][right] = index++;
            }
            right--;
            for (int i = right; i >= left; i--) {
                res[down][i] = index++;
            }
            down--;
            for (int i = down; i >= up; i--) {
                res[i][left] = index++;
            }
            left++;
        }
        return res;
    }
}

在理解完这题后,趁热打铁看第54题:

 

 这么一看,纯纯跟上一题大同小异,于是我自信的写下如下代码:

public class question54 {
    public List<Integer> spiralOrder(int[][] matrix) {
        int left = 0, right = matrix[0].length - 1, up = 0, down = matrix.length - 1;
        List<Integer> res = new ArrayList<>();
        for (int i = left; i <= right; i++) {
            res.add(matrix[up][i]);
        }
        up++;
        for (int i = up; i <= down; i++) {
            res.add(matrix[i][right]);
        }
        right--;
        for (int i = right; i >= left; i--) {
            res.add(matrix[down][i]);
        }
        down--;
        for (int i = down; i >= up; i--) {
            res.add(matrix[i][left]);
        }
        left++;
        return res;
    }
}

看起来肥肠的合理且优雅,但是当我提交的时候,出问题了:

我非常不能理解啊,于是去看了答案,才明白自己忽略了一个细节:一切的前提都是矩阵内要有数!当矩阵里的数被遍历完了以后,就不应该再继续移动指针了,我缺少了一个判断条件。应该定义一个变量用来存储矩阵内元素的个数,且每当元素添加到答案数组中后,元素的个数都要减1。

属实是细节决定成败啊,正确代码附上:

public class question54 {
    public List<Integer> spiralOrder(int[][] matrix) {
        int left = 0, right = matrix[0].length - 1, up = 0, down = matrix.length - 1;
        int numEle = matrix.length * matrix[0].length;
        List<Integer> res = new ArrayList<>();
        while (numEle >= 1) {
            for (int i = left; i <= right && numEle >= 1; i++) {
                res.add(matrix[up][i]);
                numEle--;
            }
            up++;
            for (int i = up; i <= down && numEle >= 1; i++) {
                res.add(matrix[i][right]);
                numEle--;
            }
            right--;
            for (int i = right; i >= left && numEle >= 1; i--) {
                res.add(matrix[down][i]);
                numEle--;
            }
            down--;
            for (int i = down; i >= up && numEle >= 1; i--) {
                res.add(matrix[i][left]);
                numEle--;
            }
            left++;
        }
        return res;
    }
}

我是SB我是SB我是SB,886 

举报

相关推荐

0 条评论