力扣59-螺旋矩阵(C++)

本文详细介绍了螺旋矩阵II问题的解决方案,通过在纸上绘制矩阵并分析不同大小矩阵的遍历规律,得出一个通用的遍历策略。作者强调了固定边界的重要性,并采用ijk变量在边界内移动来避免边界调整的复杂性。代码实现中,通过控制外层圈数,逐圈填充矩阵,最后处理奇数情况。该算法适用于生成指定大小的螺旋矩阵。
摘要由CSDN通过智能技术生成

59. 螺旋矩阵 II - 力扣(LeetCode) (leetcode-cn.com)icon-default.png?t=M3C8https://leetcode-cn.com/problems/spiral-matrix-ii/ 

 

思路:

找到思路的过程:在纸上自己画矩阵,n=3,4,5,画这三个(后面的太大了懒得画,而且345已经包含了奇数偶数和复杂情况了),矩阵的每行都标注上行号列号(从0开始)。

然后思考遍历方法,n=5为例,如果是每一行每一列都遍历到尾,那第一次从下往上遍历的长度是3,第一次从左到右遍历长度是5,第一次从上到下遍历的长度是4,太不规范了,按这个来太容易搞错开闭区间了,最好要是能找到一个统一的范式就好了,所以决定每行都遍历完(每行遍历个数是5),每列头尾都掐掉(每列遍历个数是3)。

n=5时发现除了中心那个点,其余行列的遍历都是一圈一圈的,这样就想到了用循环来控制总圈数,n=345找了找规律,发现圈数是n/2,而且偶数中间没有那个小圈,循环赋值完就可以输出了。

我觉得最重要的想法是不要让边界随着赋值移动,就是说定好循环的左右边界了就不要轻易改,在遍历矩阵的过程中使用ijk这样的一次性量在边界中间移动,拿代码说,下图中left,right,up,down决定了一圈循环中每条边循环的起终点,只有每一圈过完后,它们的值才会随着圈的减小而改变。

遍历中[][]里面写什么容易乱,在边较小的情况容易不知道是写0还是写i,这里有个方法,就是看它对称的边应该写什么,这俩行数加和是一个定值(找规律找出来的),然后去看这个定值和现在的行数/列数有什么关系。

代码:

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> ans(n, vector<int>(n));
        int row=n/2;//外层圈数
        int left=0,right=n,up=0,down=n;//边界
        int cnt=1;
        for(int num=0;num<row;num++)
        {
            for(int i=left;i<right;i++)//从左到右
                ans[num][i]=cnt++;

            for(int j=up+1;j<down-1;j++)//右上右下
                ans[j][right-1]=cnt++;
        
            for(int i=right-1;i>=left;i--)//从右到左
                ans[n-1-num][i]=cnt++;

            for(int j=down-1-1;j>up;j--)//左下左上
                ans[j][num]=cnt++;

            right--;
            down--;
            left++;
            up++;
        }
        if(n%2==1)//奇数
        {
            int heart=n/2;
            ans[heart][heart] = n*n;
        }
        return ans;
    }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值