59.螺旋矩阵②

题目

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

解法

要在C++中生成一个 n x n 的螺旋矩阵,其中元素按顺时针顺序排列,可以按照螺旋顺序逐步填充矩阵。类似之前的“螺旋矩阵”问题,我们需要依次遍历矩阵的边界,然后按照顺时针方向填充每个位置。

解决方案的关键点:

  • 通过定义边界(左、右、上、下)来控制矩阵的填充范围。
  • 按顺时针方向(从左到右、从上到下、从右到左、从下到上)依次填充数字。
  • 每填充完一圈,缩小边界,直到矩阵填充完毕。

代码实现:

#include <iostream>
#include <vector>

using namespace std;

vector<vector<int>> generateMatrix(int n) {
    vector<vector<int>> matrix(n, vector<int>(n, 0));  // 初始化 n x n 矩阵
    int left = 0, right = n - 1, top = 0, bottom = n - 1;  // 定义边界
    int num = 1;  // 要填充的数字

    while (left <= right && top <= bottom) {
        // 从左到右填充上边界
        for (int i = left; i <= right; ++i) {
            matrix[top][i] = num++;
        }
        top++;  // 上边界向下收缩

        // 从上到下填充右边界
        for (int i = top; i <= bottom; ++i) {
            matrix[i][right] = num++;
        }
        right--;  // 右边界向左收缩

        // 从右到左填充下边界
        if (top <= bottom) {
            for (int i = right; i >= left; --i) {
                matrix[bottom][i] = num++;
            }
            bottom--;  // 下边界向上收缩
        }

        // 从下到上填充左边界
        if (left <= right) {
            for (int i = bottom; i >= top; --i) {
                matrix[i][left] = num++;
            }
            left++;  // 左边界向右收缩
        }
    }

    return matrix;
}

int main() {
    int n = 3;  // 矩阵的大小 (n x n)
    
    vector<vector<int>> matrix = generateMatrix(n);

    // 输出矩阵
    for (const auto& row : matrix) {
        for (int elem : row) {
            cout << elem << " ";
        }
        cout << endl;
    }

    return 0;
}

代码解释:

  1. 初始化矩阵:使用 vector<vector<int>> matrix(n, vector<int>(n, 0)) 初始化一个 n x n 的全零矩阵。
  2. 定义边界leftrighttopbottom 分别表示矩阵的四个边界,初始时分别为矩阵的最外层。
  3. 填充数字:每次按顺时针方向依次填充矩阵:
    • 从左到右填充上边界。
    • 从上到下填充右边界。
    • 从右到左填充下边界。
    • 从下到上填充左边界。
      每次填充后,缩小相应的边界,直到所有数字填充完毕。
  4. 输出矩阵:按照二维数组的格式输出矩阵。

输出结果:

对于 n = 3 的情况,输出的螺旋矩阵如下:

1 2 3
8 9 4
7 6 5

复杂度分析:

  • 时间复杂度:O(n²),因为我们需要填充 个元素。
  • 空间复杂度:O(n²),需要一个 n x n 的矩阵存储结果。

该算法能够生成任意大小的螺旋矩阵。

如何创建一个纯1的矩阵?

vector<vector<int>> matrix(rows, vector<int>(cols, 1));

有点嵌套的感觉,里面再创建一个纯1的数组

奇偶矩阵的边界在何处做限制

原先不知道如何处理,因为奇偶矩阵遍历次数不一样
在这里插入图片描述
从左向右和从上到下是共同有的,但是否需要
在这里插入图片描述

if (top <= bottom)为什么要有这个限制?

  1. 避免重复遍历
    在填充矩阵的过程中,如果某一边界(如上边界 top 或下边界 bottom)已经被填充完毕并收缩,那么在后续的填充操作中就不需要再次访问这条边界。以下是这两个条件的作用:

if (top <= bottom):这个条件用于确保在填充下边界时,只有当上边界仍然在下边界之上时,才进行填充。这可以防止在 top 已经超过 bottom 的情况下,再尝试填充下边界。

if (left <= right):类似地,这个条件用于确保在填充左边界时,只有当左边界仍然在右边界之左时,才进行填充。这可以防止在 left 已经超过 right 的情况下,再尝试填充左边界。

不一定需要先把num数组做出来,可以只用Num=1,然后在过程中累加

就是我的初始解法会构造数组,但对于这种正序数组,1234567,其实有一个起点就行了。不用特意算一遍存储,节省了存储空间
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海绵波波107

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值