----------------------------2020/12/27二刷-----------------------
三个收获
1.自己打出了边界法
//设定边界法
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
if(matrix.size() == 0) return {};
int l = 0, r = matrix[0].size()-1;
int t = 0, d = matrix.size()-1;
vector<int> ans;
int index = 0;
ans.resize((r + 1)*(d + 1));
while(1) {
for(int i = l; i <= r; i ++) ans[index ++] = matrix[t][i];
if(++ t > d) break;
for(int i = t; i <= d; i ++) ans[index ++] = matrix[i][r];
if( -- r < l) break;
for(int i = r; i >= l; i --) ans[index ++] = matrix[d][i];
if( -- d < t) break;
for(int i = d; i >= t; i --) ans[index ++] = matrix[i][l];
if( ++ l > r) break;
}
return ans;
}
};
2.二刷的过程把之前深度优先的想法实现了,结果
发现纯深度优先是不行的,代码如下
class Solution {
private:
int rows, cols;
vector<vector<int>> dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
vector<int> ans;
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
if(matrix.size() == 0) return {};
rows = matrix.size();
cols = matrix[0].size();
vector<vector<int>> book (rows, vector<int> (cols, 0));
int count = rows * cols;
return dfs(0, 0, count, matrix, ans, book);
}
vector<int> dfs(int i, int j, int count,vector<vector<int>> matrix, vector<int> &ans, vector<vector<int>> &book) {
ans.push_back(matrix[i][j]);
book[i][j] = 1;
if(ans.size() == count) return ans;
for(int k = 0; k <= 3; k ++) {
int ti = i + dir[k][0];
int tj = j + dir[k][1];
if(ti >= rows || ti < 0 || tj >= cols || tj < 0|| book[ti][tj]) continue;
dfs(ti, tj, count, matrix, ans, book);
}
return ans;
}
};
为什么不行-----自己画一下面这个例子对应矩阵的路径就知道了。
3.关于引用,如果book和ans不加引用号,形参会开辟一个新的空间,这样对book的修改就没有效果。
所以如果在结构体中定义了book数组和ans数组的话,函数要么加引用,要么不要使用形参直接在函数体里面对其修改。
--------------------------------一刷------------------------------------
题目描述
解法一 深度优先进化版法
一开始的思路是用深度优先做出来,只要指定顺时针方向,用深度优先走一遍,如果没有路可以走直接break即可。
然后就觉得既然拐点处可以特殊处理,按照原本深度优先的思想,每次越界时改变方向即可,省去深度优先尝试其他方向的次数。
class Solution {
private:
int next[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
if (matrix.size() == 0 || matrix[0].size() == 0) {
return {};
}
int rows = matrix.size();
int columns = matrix[0].size();
vector<vector<bool>> book(rows, vector<bool>(columns));
int count = rows * columns;
vector<int> order(count);
int x = 0, y = 0;
int tx,ty;
int dir = 0;
for (int i = 0; i < count; i++) {
order[i] = matrix[x][y];
book[x][y] = true;
tx = x + next[dir][0];
ty = y + next[dir][1];
if (tx < 0 || tx >= rows || ty < 0 || ty >= columns || book[tx][ty]) dir = (dir + 1) % 4;
x += next[dir][0];
y += next[dir][1];
}
return order;
}
};
矩阵列数为m,行数为n
时间复杂度O(mn),空间复杂度O(mn);
解法二
一开始思考的过程中,有想过通过前面每次走完一个方向来减少另一个方向的可走次数,然后顺时针四个方向重复,直到一个方向减少到不能走为止。
但是想到深度优先觉得自己已经行了 懒就不没再去实现了。
然后看到住在精选的大佬就是这样做的…
大佬的题解
class Solution {
public int[] spiralOrder(int[][] matrix) {
if(matrix.length == 0) return new int[0];
int l = 0, r = matrix[0].length - 1, t = 0, b = matrix.length - 1, x = 0;
int[] res = new int[(r + 1) * (b + 1)];
while(true) {
for(int i = l; i <= r; i++) res[x++] = matrix[t][i]; // left to right.
if(++t > b) break;
for(int i = t; i <= b; i++) res[x++] = matrix[i][r]; // top to bottom.
if(l > --r) break;
for(int i = r; i >= l; i--) res[x++] = matrix[b][i]; // right to left.
if(t > --b) break;
for(int i = b; i >= t; i--) res[x++] = matrix[i][l]; // bottom to top.
if(++l > r) break;
}
return res;
}
}
时间复杂度O(m*n),空间复杂度O(1)