59.螺旋矩阵II(中等)

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

示例 1:

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]

示例 2:

输入:n = 1
输出:[[1]]

思路:

要坚持循环不变量原则,每一条边,横纵遍历的方式要相同,头和尾要不要遍历要确定好,也就是开闭区间,模拟顺时针画矩阵的过程:

  • 填充上行从左到右
  • 填充右列从上到下
  • 填充下行从右到左
  • 填充左列从下到上

由外向内一圈一圈画下去,一圈遍历4次,圈数则代表最外层的循环 ,在里层每条边遍历时,要确定遍历的个数,也就是确定开闭区间,这里采用左闭右开的形式遍历每条边:

关键点则在于拐角处,由于左闭右开,拐角处均让给新的一条边继续画。

在遍历每条边时,要让其中的横或者纵坐标不变,另一个在不断更新。然后有一个很重要的一点,因为4条边要写4个for循环,第一个for循环从左往右最上面开始遍历,其他三个for循环都需要记一下上一次循环索引变量的值,例如最开始第一行从左到右,i=0,j从0变到1,把两个空填上,填完后由于j当前为1,比2小,因此继续加1变成j=2,这时已经不满足for循环条件,因此进入下一个for循环。第二个for循环的时候,从上往下遍历,j=2就成为了固定不变的值,i便不断更新,依次类推进入第三个循环,第四个循环,完成一圈遍历。

由于完成一圈遍历,会进行收缩,第一行和最后一列开始遍历的时候,行数和列数均下移了一位,因此要定义两个开始的横纵坐标值为0,这两个值只在一圈循环结束的时候进行更新,因此在内层循环遍历时,用i和j去移动,在循环最开始时把横纵坐标初始值赋值给i和j。

另外圈收缩,会影响区间的长度,因此每次循环结束时,要把区间长度进行更新减1.

最后,如果n是奇数,需要单独处理一下矩形中间值。

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n,vector<int>(n,0));
        int border=1;
        int i,j,count=0,startx=0,starty=0;
        int loop=n/2;
        while(loop)
        {
            i=startx;
            j=starty;
            for(j=startx;j<n-border;j++)
            {
                count++;
                res[startx][j]=count;
            }
            for(i=starty;i<n-border;i++)
            {
                count++;
                res[i][j]=count;
            }
            for(;j>startx;j--)
            {
                count++;
                res[i][j]=count;
            }
            for(;i>starty;i--)
            {
                count++;
                res[i][j]=count;
            }
            loop--;
            border++;
            startx++;
            starty++;
        }
        if(n%2)
        {
            res[n/2][n/2]=n*n;
        }
        return res;
    }
};

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值