代码随想录刷题攻略---数组4--图形打印

例题 螺旋矩阵

给你一个正整数n,生成一个包含1到n^{2}所有元素,且元素按顺时针顺序螺旋排列的 n*n正方形矩阵matrix

模拟图像的原则:循环不变量。比如在填充该矩阵的第一行时,填充的范围是[0,n-2],那么在填充它接下来的一列时,填充范围也是[0,n-2]。

步骤:

我们先确定填充数组的方式——循环遍历每一圈

循环的圈数-->当n=偶数时,循环n/2圈;当n=奇数时,我们依然可以循环n/2圈,再对剩下的、位于数组中心的元素赋值即可

在循环过程中,每一圈的 i,j 起始位置会发生变化,所以我们用两个变量 startx,starty 作为 每次循环 i,j落脚点。而 i,j 在不同圈中的终止位置也不同,可以用一个变量 endxy 表示,每一圈下来都减1。

code:

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n,vector<int>(n));
        int count=1;//填充数
        int startx = 0, starty = 0;//每一圈的起始位置
        int endxy=n-1;//每一圈的结束位置
        int loop = n/2;
        while(loop--)//填充每一圈
        {
            int i,j;
            for(j=starty; j<endxy; j++)
                res[startx][j] = count++;          
            for(i=startx; i<endxy; i++)
                res[i][j] = count++;
            for(; j>starty; j--)
                res[i][j] = count++;
            for(; i>startx; i--)
                res[i][j]=count++;
            startx++;
            starty++;
            endxy--;//右边缩短一个单位
        }
        if(n%2 == 1)//是奇数矩阵
        res[n/2][n/2] = count;
        return res;
    }  
};

例题2: 螺旋矩阵

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

这一题跟例题相似,都是遍历螺旋矩阵。

但不同的是,此题的 m ≠ n,单纯判断圈数、设置起始位置终止已经不好使了。(比如矩阵为4x3时,循环不变量在第二圈失效)

 这题的思想是,既然无法控制循环不变量,那我们每一行、每一列都遍历到底,重叠访问的矩阵元素,我们不要push_back入向量的下一个元素,push_back在上一个重合的元素即可。

在遍历矩阵的过程中,我们每遍历完一行、一列(边界收缩),就将这一行、一列从原矩阵中消除掉(逻辑上),逐渐消除成只剩一行或一列(边界相遇)

code:

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        if (matrix.empty()) return {};
        int l = 0, r = matrix[0].size() - 1, t = 0, b = matrix.size() - 1;
        vector<int> res;
        while(1)
        {//for循环都 <= 终止位置,使res数组里的数可以重合
            for(int i = l; i <= r; i++) res.push_back(matrix[t][i]);
            if(++t > b) break;//只有一层 退出
            for(int i = t; i <= b; i++) res.push_back(matrix[i][r]);
            if(l > --r) break;//只有一列
            for(int i = r; i >= l; i--) res.push_back(matrix[b][i]);
            if(t > --b) break;//削减后只有一层了
            for(int i = b; i >= t; i--) res.push_back(matrix[i][l]);
            //if(l > --r) break;//削减后只有一列了
            if(++l > r) break;
        }
        return res;
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值