算法题解记录4+++螺旋矩阵(百日筑基)

题目描述:

        给你一个 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

解题准备:

        1.了解可能存在的基础操作:本题要求按照顺时针螺旋返回数组中所有元素,本质就是按某种形式遍历数组所有元素,并且返回元素数据。

        由于没有载体,所以要临时创建一个实例作为载体,即List<Integer>,实例初值为null,所以应添加数据。

        11st.那么,就有两个操作:查找、添加。

        2.纸上模拟操作,找一下规律:

                明显可以发现,该遍历是从外到里,一层层遍历。

                如果单独一层遍历,那么就满足先上、再右、再下、再左(边缘的划分条件可以自由抉择,我指的是:可以把0、0看成上,1、4、7看成右;;也可以把0、0、1看成上,4看成右,7、6、5看成下)

解题难点分析1:

        本题最难的地方,不在于找出规律,而是如何用算法的语言,把规律描述出来。

        1.最重要的第一步,是界定变量:需要用几个变量来描述规律,这些变量的作用分别是什么?

        由上述的规律,我们假设攻破了一层,接下来的问题都迎刃而解(即,认为每一层都很完整,并且可以由第一层推导得到)

        那么,第一层有四步:上、右、下、左。

        上的遍历,只要求一个变量:top。由于行不变,仅列变,所以用top界定行正好,列可能需要一个变量temp1表示。

        右的遍历,同样要求一个遍历:right、temp2。

        同理,下:bottom;左:left。以及两个temp。

        目前有8个变量,4个temp。

        问题1:这些变量是否可以合并简化?

                这个问题先放在一边,目前看不出能否简化。

        问题2:这些变量,应该如何遍历每一层?

                上:我们用top界定了行数,top初值为0(对于第一层,这个数为0,第二层,这个数为1,也就是每次遍历一层,都要top+1【遍历结果】),那么只要temp做好即可。【遍历得到matrix【top】【temp】】

                        temp如何界定?如果是第一层,明显是从0到column-1(列-1),第二层,则为1到column-2(列-2),用代码实现也不难,但是有点复杂,我们既然用left、right界定左右,那么能不能借助left、right呢?

                右:用right界定列数,同理,遍历得到matrix【temp】【right】。temp,则需要用top和bottom界定。初值:column-1,遍历结果:right-1

                下:同理,初值bottom为row-1,结果为bottom-1。

                左:同理。初值:0,结果:left-1。

        由于界定,每完整的一层,遍历得到的结果应该一致。(也就是不会遗漏、不会多出)

解题难点分析2:

        目前我们知道,最内侧的一层,很可能不是完整的,比如3*3的矩阵(即本例),其中只有“上”,没有其它。

        由于解题难点分析1已知,对于完整的一层,遍历结果一致,那么,对于残缺的一层,我们的重点应该在于,如何跳出循环?【其它的都一致,只要不多出重复元素,结果就符合题意】

        也就是说,如何设定结束条件?【答案在下】

解题:

                由于代码必然是迭代的,所以要求一致性,在这里按照下面的顺序进行遍历:

        如图易得,上层的temp,从left开始,一直遍历到right;每次结束,top+1

        右层temp,则从top开始,一直到bottom;同理

        其它同理。

        1.这里有有个问题:遍历总有结束,结束条件是什么?

        如果从上下左右的关系来看,必然有top<=bottom,left<=right。【按照上述顺序遍历的解法,不太好写代码】

        不过,由于该题要求遍历所有元素,而一个矩阵的元素有row*column==num个,所以只要遍历个数不达到num,都可以认为遍历未完成。

代码:

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        LinkedList<Integer> result = new LinkedList<>();
        if(matrix==null||matrix.length==0) return result;
        int top=0, left=0, bottom=matrix.length-1, right=matrix[0].length-1;
        // 减1是因为从0开始数
        int num = matrix.length*matrix[0].length;

        // 这个条件,是指只要遍历到足够的数量,就退出。
        while(num>0){
            // temp<=的原因:只要在上层,都遍历
            for(int temp=left; temp<=right && num>0; temp++){
                result.add(matrix[top][temp]);
                num--;
            }
            top++;
            // temp<=的原因:top已经++,不担心top的重复,并且只要在右,都遍历
            for(int temp=top; temp<=bottom && num>0; temp++){
                result.add(matrix[temp][right]);
                num--;
            }
            right--;
            // temp>=的原因:right已经--,不担心right的重复,并且只要在下,都遍历
            for(int temp=right; temp>=left && num>0; temp--){
                result.add(matrix[bottom][temp]);
                num--;
            }
            bottom--;
            // temp>=的原因:bottom已经--,不担心bottom的重复,并且只要在左,都遍历
            for(int temp=bottom; temp>=top && num>0; temp--){
                result.add(matrix[temp][left]);
                num--;
            }
            left++;
        }

        return result;
    }
}

收尾:

        易知,(四个temp、上下左右)8个变量都不好取舍,故都应该保留。

以上内容即我想分享的关于力扣热题4的一些知识。

        我是蚊子码农,如有补充,欢迎在评论区留言。个人也是初学者,知识体系可能没有那么完善,希望各位多多指正,谢谢大家。

        

  • 15
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值