今天做了一下螺旋矩阵主题的一系列题目
即力扣中的相似题目
还是有所感悟的
接下来一一回顾:
第一题:
59. 螺旋矩阵 II - 力扣(LeetCode)
这题让我们生成一个正方形的矩阵,注意是正方形,不是长方形,所以这里我可以while循环里用计数的方法,cnt计数器累加填数直到和n*n相等
边界问题就是left right up down 还是非常常规简单的
代码如下:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> vec(n,vector<int> (n) );
int left=0,right=n-1,up=0,down=n-1;int cnt=1;
while(cnt<=n*n)
{
for(int i=left;i<=right;i++){vec[up][i]=cnt++;}up++;
for(int j=up;j<=down;j++){vec[j][right]=cnt++;}right--;
for(int i=right;i>=left;i--){vec[down][i]=cnt++;}down--;
for(int j=down;j>=up;j--){vec[j][left]=cnt++;}left++;
}return vec;
}
};
当然了你这里vector的二维数组要会定义:vector<vector<int>> vec(10,vector<int>(10))
接下去第二题:
54. 螺旋矩阵 - 力扣(LeetCode)
这题其实和第一题一模一样 换汤不换药
但是值得注意的是 第二题这里 不是固定的正方形了 可以是任意的矩形 也就是说长方形也行
这样的话我们就不能再用计数法来表示终止条件 因为有可能会产生边界问题
所以我们直接多写几个left<=right up<=down即可 代码如下:
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int m=matrix.size(),n=matrix[0].size();//m行n列
vector<int> res;
int left=0,up=0,right=n-1,down=m-1;
while(left<=right&&up<=down)//矩形为非正方形的时候有可能造成边界问题
{
if(up<=down)for(int i=left;i<=right;i++){res.push_back(matrix[up][i]);}up++;
if(right>=left)for(int j=up;j<=down;j++){res.push_back(matrix[j][right]);}right--;
if(down>=up)for(int i=right;i>=left;i--){res.push_back(matrix[down][i]);}down--;
if(left<=right)for(int j=down;j>=up;j--){res.push_back(matrix[j][left]);}left++;
}return res;
}
};
第三题:
885. 螺旋矩阵 III - 力扣(LeetCode)
这道题目有几个要素:
要素1:每次东南西北走的顺序,每次的步长是不一样的,我现在模拟开始,往东走1往南走1往西走2往北走2往东走3往西走3……也就是说 每走两步 步长+1
要素2:这里未来方便走路 可以写方向数组
每次一个for循环 step表示步长 就是在这个方向走多少次
如果当前点没有越界 就放入结果数组即可
我定义一个方向0123表示东西南北 以及下标访问方向数组 当我方向为1或者3的时候 step就可以++
然后方向+1再%4就是新的方向
代码如下:
class Solution {
public:
vector<vector<int>> spiralMatrixIII(int rows, int cols, int rStart, int cStart) {
//螺旋形状从里到外的话 定义方向数组 东南西北的顺序 每走两步 步长+1
//终止条件:结果数组的长度等于实际要求的长度就行
int dx[]={0,1,0,-1}; int dy[]={1,0,-1,0};
int step=1,cnt=0,d=0;//d是方向的意思
vector<vector<int>> res;
int curx=rStart,cury=cStart;
res.push_back({rStart,cStart});cnt++;
if(cnt==rows*cols)return res;
while(1)
{
for(int i=0;i<step;i++)//每个方向要走的步数
{
curx+=dx[d];cury+=dy[d];
if(curx>=0&&curx<=rows-1&&cury>=0&&cury<=cols-1){res.push_back({curx,cury});cnt++;}
if(cnt==rows*cols)return res;
}
if(d==1||d==3)step++;
d=(d+1)%4;
}
}
};
第四题:
2326. 螺旋矩阵 IV - 力扣(LeetCode)
这一题实际上也不是特别难
有一个小妙招:初始化结果列表的时候 直接-1填满就行 这样最后不够也能结束
那么结束条件是什么呢?head为空或者越界
所以while里面就left<=right&&up<=down&&head即可
需要注意的是初始化-1vector的写法:vector<vector<int>> vec(10,vector<int>(10,-1))
代码如下:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: vector<vector<int>> spiralMatrix(int m, int n, ListNode* head) { int left = 0, right = n - 1, up = 0, down = m - 1; vector<vector<int>> res(m, vector<int>(n, -1)); while (left <= right && up <= down && head) { if (up <= down && head) { for (int i = left; i <= right && head; i++) { res[up][i] = head->val; head = head->next; } up++; } if (left <= right && head) { for (int j = up; j <= down && head; j++) { res[j][right] = head->val; head = head->next; } right--; } if (up <= down && head) { for (int i = right; i >= left && head; i--) { res[down][i] = head->val; head = head->next; } down--; } if (left <= right && head) { for (int j = down; j >= up && head; j--) { res[j][left] = head->val; head = head->next; } left++; } } return res; } };
以上就是《螺旋矩阵》家族的所有成员 连座!
这就是本期所有内容了 下期再见 rich!