算法
(模拟) $O(n^2)$
我们顺时针定义四个方向:上右下左。
从左上角开始遍历,先往右走,走到不能走为止,然后更改到下个方向,再走到不能走为止,依次类推,遍历 $n^2$ 个格子后停止。
时间复杂度
矩阵中每个格子遍历一次,所以总时间复杂度是 O(n^2)。
C++ 代码
class Solution {
public:
vector<int> printMatrix(vector<vector<int>>& matrix) {
vector<int> res;
if (matrix.empty()) return res;
int n = matrix.size(), m = matrix[0].size();
vector<vector<bool>> st(n, vector<bool>(m, false));
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int x = 0, y = 0, d = 1;
for (int k = 0; k < n * m; k ++ )
{
res.push_back(matrix[x][y]);
st[x][y] = true;
int a = x + dx[d], b = y + dy[d];
if (a < 0 || a >= n || b < 0 || b >= m || st[a][b])
{
d = (d + 1) % 4;
a = x + dx[d], b = y + dy[d];
}
x = a, y = b;
}
return res;
}
};
我的方法一样,写的代码好丑,好烦
这样虽然用了额外空间 但是好容易写啊!
Y总NB!
对滴,比定义4个边界好写多了hh
差
想请问下为何将d初始设为1了,我尝试过后发现d=0,d=1都可以通过,但d=2,d=3无法通过。
0,1,2,3分别表示上、右、下、左四个方向。每次如果沿当前方向走会出边界或者走到重复格子,就会自动转90度。所以
为什么是上右下左呢?一直想不明白这个为什么 上是d[x]=-1,右是d[x]=0,后面全乱了。
问怎么算出那个数组的的呢?
建议参考视频讲解,有图的。AcWing 40. 顺时针打印矩阵。
为啥是上右下左啊,视屏里没看见图啊,0对应的不是dx.dy为(-1,0)吗?-1,0不是左移1格,y移动0格,这样应该是向左啊,还是我的坐标系不对
我明白了!是我坐标系建立错了,x轴是向下,y轴向右建立坐标系。
每次循环输出一圈,一圈分四个方向,每次走到头,直到四个方向都输出完成
y总为什么这个代码需要特判呢?if (matrix.empty()) return res;
class Solution {
public:
vector[HTML_REMOVED] printMatrix(vector[HTML_REMOVED] > matrix) {
vector[HTML_REMOVED] v;
if(matrix.empty())return v; //if判断在这里就可以
int n=matrix.size();
int m=matrix[0].size();
bool vis[n][m];
memset(vis,false,sizeof(vis));
int dis[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int x=0,y=0,d=0;
int a,b;
if(n==0||m==0)return v;
//if(matrix.empty())return v; //在这里就不可以,很奇怪啊
for(int i=0;i[HTML_REMOVED]=n||b<0||b>=m||vis[a][b]){
d=(d+1)%4;
a=x+dis[d][0];
b=y+dis[d][1];
}
x=a;y=b;
}
return v;
}
};
class Solution {
public:
int D[4][2]={{1,0},{0,-1},{-1,0},{0,1}};
int rows,cols;
inline void dfs(vector[HTML_REMOVED] > matrix,vector[HTML_REMOVED]s,int i, int j)
{
if(i<0||i>=rows||j<0||j>=cols)
return;
if(matrix[i][j]==-1<<30)
return;
s.push_back(matrix[i][j]);
matrix[i][j]=-1<<30;
for(int x=0;x<4;x++)
{
int ex=i+D[x][0];
int ey=i+D[x][1];
dfs(matrix,s,ex,ey);
}
}
vector[HTML_REMOVED] printMatrix(vector[HTML_REMOVED] > matrix) {
rows=matrix.size();
vector[HTML_REMOVED] s;
s.clear();
if(rows==0)
return s;
cols=matrix[0].size();
dfs(matrix,s,0,0);
return s;
}
};
为啥这样写什么也没输出
yyds
niu
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
请问一下,这个坐标系不能随便构建吗?
看d的初始值 相对顺序是一样的
为什么这里的语序调整了一下就不能再输入[]时输出[]了??
int n=matrix.size(); if(!n) return res; int m=matrix[0].size();
int n=matrix.size(); int m=matrix[0].size(); if(!n) return res;
同问
因为[]没有元素呀,matrix[0]属于非法访问,越界了
if (a < 0 || a >= n || b < 0 || b >= m || st[a][b])写成while(a < 0 || a >= n || b < 0 || b >= m || st[a][b])就会Time Limit Exceeded了,是不是因为到最后一个位置的时候st[a][b]一直为真在while循环中出不来了呀?
为什么要定义一个a和b,直接写x=x+dx[d],y=y+dy[d]不可以么? (而且提交还报错了)
这里的x和y要用于存储x,y原先的状态,后面对不合要求的a,b更改的时候还会用到x,y,另外在bfs回溯中通常需要使用a,b作为临时变量暂存x和y的状态,以便在回溯过程中恢复x,y以前的转态,你可以看看第23题:矩阵中的路径
在往下一步走之前需要先试探一下能不能走,如果不能走的话需要拐个弯。
请问下这种情况可以通过 if ( a < 0 || a >= n || b < 0 || b >= m || st[a][b])
而 if ( st[a][b] || a < 0 || a >= n || b < 0 || b >= m)却报错这是为什么
if ( a < 0 || a >= n || b < 0 || b >= m || st[a][b])
这句话,如果a
或者b
不在范围内,就不会调用st[a][b]
了。谢谢大佬