leetcode-59 螺旋矩阵

59. 螺旋矩阵 II - 力扣(LeetCode)
题目标签:数组、
题目简述:将一个数组,螺旋地写进方阵中
相似题目:

  • 解题思路:
    1. 操作坐标增量
      • 使用方向向量dx, dyxy 进行操作
      • x = x +dx; y = y + dy;
      • 注意事项:
        • 第一次在做题目时候没有使用使用nx 与ny 做为中间变量导致数组访问越界。下面浅析一下原因:
        • 如果直接修改 x 和 y,那么在下一个判断条件或操作中使用 x 和 y 时,就会使用已经被修改过的值,这可能导致逻辑错误或意外的行为。通过先计算 nx 和 ny,我们可以在确认它们是有效位置之后再更新 x 和 y。
    2. 坐标循环
      • 使用四个for循环控制四个方向上坐标的变化
	// 简单例子
	x += dx[direction];  
	y += dy[direction];  
	if (/* 检查 (x, y) 是否有效 */) {  
	    // ... 填充矩阵等操作 ...  
	} else {  
	    // 如果 (x, y) 无效,我们就需要往后退一步,不然就是在边界外向沿着更新的方向前进  
	    x -= dx[direction];  
	    y -= dy[direction];  
	    // 然后改变方向并重新计算新的位置  
	}
  • 代码:
// 个人解法 同acwing
## 一. 操作坐标的增量
class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n, vector<int>(n, 0));
        vector<vector<bool>> status(n, vector<bool>(n, false));
		
        int dx[4] = {0, 1, 0, -1};
        int dy[4] = {1, 0, -1, 0};
        int x = 0, y = 0;
        int c = 0; //初始方向
        // 循环量的更新不会,导致超出边界
        for(int i = 1; i <= n*n; i++) {
            res[x][y] = i;
            status[x][y] = true;
            // 定义下个点的位置,并且在最后放回
            int nx = x + dx[c % 4];
            int ny = y + dy[c % 4];
            if(nx < 0 || nx >= n || ny < 0 || ny >= n || status[nx][ny]) {
                c ++;
                // 如果超出边界,就要重新定义 下个点的位置
                nx = x + dx[c % 4];
                ny = y + dy[c % 4];                
            }    
            x = nx;
            y = ny;
        }
        return res;
    }
};
// 二. 坐标循环
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; // 每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理
        int mid = n / 2; // 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)
        int count = 1; // 用来给矩阵中每一个空格赋值
        int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位
        int i,j;
        while (loop --) {
            i = startx;
            j = starty;

            // 下面开始的四个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++;
            }
			
            // 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
            startx++;
            starty++;
			
            // offset 控制每一圈里每一条边遍历的长度
            offset += 1;
        }
		
        // 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
        if (n % 2) {
            res[mid][mid] = count;
        }
        return res;
    }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值