题目描述(中等难度)
算法
(模拟)
相似的题目有:54. 螺旋矩阵
LeetCode 54,59,885题解 | 螺旋矩阵I,II,II(蛇形矩阵 C++代码)
- 遍历过程中只有四个方向,而且是按顺序选择方向的
- 我们将做n*m次循环
- 每次循环先把当前可走的点加到res中
- 然后利用(a,b)找到下一个可以走的点
- 再让(x,y)变成下一个可走的点,然后进入下一个循环
- 由于往右和往下的方向每次最多走一次,所以每次循环结束后我们要提前改变一次方向,这样下次循环会在对角线方向找下个可行点
注意:最后一次循环只要把点加到res后,就要break,因为最后一点的已经找不到下一个可走的点了
代码1和代码2思路是一样的,只不过空间复杂度上稍微有点不同
C++代码1
时间复杂度是 ,空间复杂度是 :用了一个st来标记
class Solution {
public:
vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
if(!matrix.size() || !matrix[0].size()) return {};
int n = matrix.size(), m = matrix[0].size();
vector <int> res;
vector<vector<bool>> st(n, vector<bool>(m, 0));
int dx[] = {0, 1, 1, -1}, dy[] = {1, -1, 0, 1};
int x = 0, y = 0, d = 0;
for (int i = 1; i <= n * m; i ++) {
res.push_back(matrix[x][y]);
st[x][y] = true;
if (i == n * m) break;
// 利用(a,b)找到下一个可以走的点
int a = x + dx[d], b = y + dy[d];
while(a < 0 || a >= n || b < 0 || b >= m || st[a][b] == true) {
d = (d + 1) % 4;
a = x + dx[d], b = y + dy[d];
}
// 让(x,y)变成下一个可走的点,然后进入下一个循环
x = x + dx[d];
y = y + dy[d];
// 往右和往下的方向每次最多走一次,所以要提前改变一次方向
if (d == 0 || d == 2) d = (d + 1) % 4;
}
return res;
}
};
C++代码2
时间复杂度是 ,空间复杂度是 :直接利用改matrix的值来判断是否遍历过
class Solution {
public:
vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
if(!matrix.size() || !matrix[0].size()) return {};
int n = matrix.size(), m = matrix[0].size();
vector <int> res;
int dx[] = {0, 1, 1, -1}, dy[] = {1, -1, 0, 1};
int x = 0, y = 0, d = 0;
for (int i = 1; i <= n * m; i ++) {
res.push_back(matrix[x][y]);
matrix[x][y] = INT_MAX;
if (i == n * m) break;
// 利用(a,b)找到下一个可以走的点
int a = x + dx[d], b = y + dy[d];
while(a < 0 || a >= n || b < 0 || b >= m || matrix[a][b] == INT_MAX) {
d = (d + 1) % 4;
a = x + dx[d], b = y + dy[d];
}
// 让(x,y)变成下一个可走的点,然后进入下一个循环
x = x + dx[d];
y = y + dy[d];
if (d == 0 || d == 2) d = (d + 1) % 4;
}
return res;
}
};
写在最后:我的博客主要是对计算机领域所学知识的总结、回顾和思考,把每篇博客写得通俗易懂是我的目标,分享技术和知识是一种快乐 ,非常欢迎大家和我一起交流学习,有任何问题都可以在评论区留言,也期待与您的深入交流(^∀^●)