题解 | 螺旋矩阵 这个边界收缩的方法很妙

螺旋矩阵

https://www.nowcoder.com/practice/7edf70f2d29c4b599693dc3aaeea1d31

只要有一条边不满足条件(即边界发生交叉),就意味着矩阵中所有剩余的元素都已经被遍历完了,或者根本不存在剩余元素了。 继续执行只会导致重复遍历或数组越界。
这是一个非常深刻且关键的问题!这触及了螺旋矩阵算法的核心逻辑。
简单来说,只要有一条边不满足条件(即边界发生交叉),就意味着矩阵中所有剩余的元素都已经被遍历完了,或者根本不存在剩余元素了。 继续执行只会导致重复遍历或数组越界。
我们可以通过分析边界收缩的过程来理解这一点。
核心思想:边界交叉 = 遍历结束
螺旋遍历的本质是逐层剥离矩阵。每完成一个方向的遍历,我们就会将对应的边界向内收缩一步。
up > down:意味着上边界已经跑到了下边界的下面。说明所有行都处理完了。
left > right:意味着左边界已经跑到了右边界的右边。说明所有列都处理完了。
只要发生以上任何一种情况,就说明“地盘”已经被瓜分完毕,没有新的、未访问的元素了。

#include <vector>
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param matrix int整型vector<vector<>> 
     * @return int整型vector
     */
    vector<int> spiralOrder(vector<vector<int> >& matrix) {
        // write code here
          vector<int> res;
        int row=matrix.size();
        if(row==0)return res;
        int col=matrix[0].size();
        /*
        卡尔讲的循环不变量很精彩 但官解更胜一筹。
        都是按照顺时针方向(右 -> 下 -> 左 -> 上)一圈一圈地“剥洋葱,只要保持这个顺序对了 且一次只访问边界 并且没有重复访问 并且有终止条件 那他就是正确的
        这个叫做边界收缩法。
        */
        // vector<int> res(row*col);
        //这里不应该初始化啊,不然结果数组的前 row*col 个元素全是 0,后面才接上你遍历出来的真实数据
      
        if(row==0||col==0)return res;
        int up=0,left=0,right=col-1,down=row-1;
        while((up<=down)&&(right>=left)){
            if(right>=left){
                for(int i=left;i<=right;i++){
                    res.push_back(matrix[up][i]);
                }
            }
            else break;
            up++;
            if(up<=down){
                for(int i=up;i<=down;i++){
                    res.push_back(matrix[i][right]);
                }
            }
            else break;
            right--;
             if(right>=left){
                for(int i=right;i>=left;i--){
                    res.push_back(matrix[down][i]);
                }
            }
            else break;
            down--;
            if(up<=down){
                for(int i=down;i>=up;i--){
                    res.push_back(matrix[i][left]);
                }
            }
            else break;
            left++;
        }
        return res;
    }
};

全部评论

相关推荐

牛奶配面包:第二个经典博弈题目吧
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务