[コードのランダムな思考 | Leetcode | 4 日目] 配列 | スパイラル マトリックス | 59

序文

Little KLeetcode | Code Random Records | テーマ別コラムへようこそ、今日はスパイラルマトリックスをシェアします✨


59. スパイラルマトリックスⅡ

正の整数を指定するとn、 1 から n 2までのすべての要素を時計回りの螺旋順序で含むn x n 正方行列を生成しますmatrix

例 1:
ここに画像の説明を挿入

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

例 2:

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

ヒント:

1 <= n <= 20

アイデア:

このタイプのトピックには実際にはアルゴリズムは含まれません。スパイラル順に印刷するプロセスをシミュレートするものです。以下でシミュレートしてみましょう。

  • 上の行を左から右に埋めていきます
  • 右の列を上から下まで埋めてください
  • 降順の行を右から左に埋めていきます
  • 左の列を下から上に埋めていきます

しかし、このようなシミュレーションの循環には多くの境界条件が存在し、間違いを犯しやすいことがわかります。このとき、最初のセクションで学んだ二分法で使用されるループ不変規則が非常に重要です

マトリックスの 4 つの辺は、左が閉じて右が開いているか、左が開いていて右が閉じています。
ここに画像の説明を挿入
ここに画像の説明を挿入

class Solution {
    
    
public:
    vector<vector<int>> generateMatrix(int n)
    {
    
    
        vector<vector<int>> res(n,vector<int>(n,0));
        int startx=0,starty=0;  //定义每循环一个圈的起始位置
        int loop=n/2; //每个圈循环几次,如果n为奇数3,那么loop=1,只循环一圈
        int mid=n/2;  //矩阵中间位置,例如n为3,中间的位置为【1,1】
        int count=1;  //用来给矩阵元素赋值的
        int offset=1; //用来控制循环遍历长度
        int i,j;
        while(loop--)
        {
    
    
            i=startx,j=starty;
            //左闭右开
            for(j=starty;j<starty+n-offset;j++) res[startx][j]=count++;
            for(i=startx;i<startx+n-offset;i++) res[i][j]=count++;
            for(;j>starty;j--) res[i][j]=count++;
            for(;i>startx;i--) res[i][j]=count++;
            //第二圈开始,起始位置要各自加一
            startx++,starty++;
            offset+=2;
        }
        //如果n为奇数,则需要单独给矩阵之间的位置赋值
        if(n%2) res[mid][mid]=count;
        return res;
    }
   
};

シミュレーションのプロセスは上記のコードで詳しく説明されていますが、特に次の 2 つの点を説明します。

  • starty+n-offset: 2 番目の円の開始座標が 0 ではないため、なぜここに開始位置が追加されるのか
  • offset+=2: なぜ 2 を加えるかというと、一周するたびに両端の要素が欠落し、左閉じ右開きの原理に従って初期値が 1 になるためです。
  • 3 3 と 4 4 のシミュレーション図があります。

要約する

この種のトピックを実行するには、より多くのシミュレーションを描く必要がありますが、境界条件に注意を払って明確に考えるのは簡単です (ループ不変性のルールに従う)

おすすめ

転載: blog.csdn.net/qq_72157449/article/details/131745498