代码随想录 day2 | 59.螺旋矩阵II

文档讲解:https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html
视频讲解:https://www.bilibili.com/video/BV1SL4y1N7mV/
看讲解前状态:不会
看讲解后状态:有思路但不会
二刷状态:

基础知识:

  • vector<vector<int>> res(n1, vector<int>(n2, 0));
    这行代码的作用是创建一个大小为 n1xn2 的二维整数向量(矩阵)res,其中每个元素都初始化为整数值 0

    • vector<vector<int>>:这是C++标准库中的容器之一,用于存储多维数据结构。在这里,我们使用了 vector 来创建一个存储整数类型的二维向量,即矩阵。

    • res:这是你所创建的二维整数向量(矩阵)的名称。

    • n1:表示矩阵的行数。

      • n1也为外层 vector 的大小,即包含了 n 个内层 vector 的元素。
    • n2:表示矩阵的列数。

    • vector<int>(n2, 0):这是内层的 vector 初始化。它创建了一个包含 n2 个整数元素的向量,并将每个元素初始化为 0。

  • 这种操作通常用于初始化一个二维数组,矩阵或表格,以便在后续的计算或操作中存储数据。

题目:

https://leetcode.cn/problems/spiral-matrix-ii/

法一:

解题关键:

  • 关键:四个边界循环不变量原则,边界处理区间规则要统一
    • 每圈每边处理[起始-倒二](包起始,包倒二),可用左闭右开、左闭右闭表示,本质一样)
    • 同二分法类似,边界坚持循环不变量原则:从头到尾坚持[左闭右开)或[左闭右闭]。

解题思路:

  • 总圈数: 由题,总共应转n/2圈。

    • 若n为偶数,则n/2圈后截止。
    • 若n为奇数,则n/2圈后还剩最中心位置一个空处,单独填入最后一个元素即可。
      • 最中间位置:(int(n/2),int(n/2))
  • 每圈起始位置:

    • 每一圈起始位置是变化的。所以需单独定义变量存放起始位置。
      • (startX,startY),每转一圈(startX++,startY++)
  • 每边起始位置

    • 每圈第一边起始位置(startx,starty),
    • 之后每一边:
      • 左闭右开则为上一次结束位置(i,j)
      • 左闭右闭则为上一次结束位置:
        - 行转圈则为(i,j+/-1)
        - 列转圈则为(i+/-1,j)
  • 矩阵元素位置用(i,j)坐标存放。

    • 行 只改变j,
    • 列 只改变i,
  • 当前圈数:决定每圈边长(每边终止位置)。

    • 当前圈数offset从1开始
    • 每边终止:例如行:(i,j)左闭右开则j<n-offset;左闭右闭则j<=n-offset-1
代码实现:
class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n,vector<int>(n,0));//使用vector定义一个二维数组
        int startx = 0,starty=0;//定义每循环一个圈的起始位置
        int loop = n/2;//一共要循环几个圈 
        int mid =n/2;//矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)
        int count = 1;//用于给矩阵中每一个空格赋值,从1开始++到n^2
        int offset = 1;//当前圈数,用于控制每一条边遍历的长度(终止位置),每次循环右边界收缩一位
        int i,j;//(i,j)坐标,用于遍历矩阵中每个单元格
        while (loop--){
            i = startx;
            j = starty;
            
            //下面模拟循环转一圈:4个for循环
            //模拟填充上行从左到右(左闭右开)
            for (j = starty;j<n-offset;j++){
                res[startx][j] = count++;
            }
            for (i=startx;i<n-offset;i++){
                res[i][j] = count++;
            }
            for (;j>starty;j--){
                res[i][j] = count++;
            }
            for (;i>startx;i--){
                res[i][j]=count++;
            }

            //每开始新的一圈,起始位置要在上一圈基础上(startx+1,starty+1)
            startx++;
            starty++;

            //offset为当前圈数,从1开始,来控制终止位置(每圈循环各边的遍历长度)
            offset++;
        }

        //如果n为奇数的话,需要单独给矩阵最中间的空格(mid,mid)赋值n^2
        if (n%2 ==1){
            res[mid][mid] = count;
        }
        return res;

    }
};
时间复杂度:O(n^2)
空间复杂度:O(1)

☹☹☹遇到的问题:

  • offset初始值最开始想错了。
  • vector创建二维原理不熟悉。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值