31
31
32
32
## 解法
33
33
34
+ ** 方法一:模拟**
35
+
36
+ 我们用 $i$ 和 $j$ 分别表示当前访问到的元素的行和列,用 $k$ 表示当前的方向,用数组或哈希表 $vis$ 记录每个元素是否被访问过。每次我们访问到一个元素后,将其标记为已访问,然后按照当前的方向前进一步,如果前进一步后发现越界或者已经访问过,则改变方向继续前进,直到遍历完整个矩阵。
37
+
38
+ 时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。
39
+
40
+ ** 方法二:逐层模拟**
41
+
34
42
从外往里一圈一圈遍历并存储矩阵元素即可。
35
43
44
+ 时间复杂度 $O(m \times n)$,空间复杂度 $O(1)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。
45
+
36
46
<!-- tabs:start -->
37
47
38
48
### ** Python3**
39
49
40
50
``` python
41
51
class Solution :
42
52
def spiralOrder (self , matrix : List[List[int ]]) -> List[int ]:
43
- def add (i1 , j1 , i2 , j2 ):
44
- if i1 == i2:
45
- return [matrix[i1][j] for j in range (j1, j2 + 1 )]
46
- if j1 == j2:
47
- return [matrix[i][j1] for i in range (i1, i2 + 1 )]
48
- return (
49
- [matrix[i1][j] for j in range (j1, j2)]
50
- + [matrix[i][j2] for i in range (i1, i2)]
51
- + [matrix[i2][j] for j in range (j2, j1, - 1 )]
52
- + [matrix[i][j1] for i in range (i2, i1, - 1 )]
53
- )
53
+ if not matrix or not matrix[0 ]:
54
+ return []
55
+ dirs = (0 , 1 , 0 , - 1 , 0 )
56
+ m, n = len (matrix), len (matrix[0 ])
57
+ vis = [[False ] * n for _ in range (m)]
58
+ ans = []
59
+ i = j = k = 0
60
+ for _ in range (m * n):
61
+ ans.append(matrix[i][j])
62
+ vis[i][j] = True
63
+ x, y = i + dirs[k], j + dirs[k + 1 ]
64
+ if x < 0 or y < 0 or x >= m or y >= n or vis[x][y]:
65
+ k = (k + 1 ) % 4
66
+ x, y = i + dirs[k], j + dirs[k + 1 ]
67
+ i, j = x, y
68
+ return ans
69
+ ```
54
70
71
+ ``` python
72
+ class Solution :
73
+ def spiralOrder (self , matrix : List[List[int ]]) -> List[int ]:
55
74
if not matrix or not matrix[0 ]:
56
75
return []
57
76
m, n = len (matrix), len (matrix[0 ])
58
- i1, j1, i2, j2 = 0 , 0 , m - 1 , n - 1
59
- res = []
60
- while i1 <= i2 and j1 <= j2:
61
- res += add(i1, j1, i2, j2)
62
- i1, j1, i2, j2 = i1 + 1 , j1 + 1 , i2 - 1 , j2 - 1
63
- return res
77
+ ans = []
78
+ top, bottom, left, right = 0 , m - 1 , 0 , n - 1
79
+ while left <= right and top <= bottom:
80
+ ans.extend([matrix[top][j] for j in range (left, right + 1 )])
81
+ ans.extend([matrix[i][right] for i in range (top + 1 , bottom + 1 )])
82
+ if left < right and top < bottom:
83
+ ans.extend([matrix[bottom][j] for j in range (right - 1 , left - 1 , - 1 )])
84
+ ans.extend([matrix[i][left] for i in range (bottom - 1 , top, - 1 )])
85
+ top, bottom, left, right = top + 1 , bottom - 1 , left + 1 , right - 1
86
+ return ans
64
87
```
65
88
66
89
### ** Java**
67
90
68
91
``` java
69
92
class Solution {
70
- private int [] res;
71
- private int index;
72
-
73
93
public int [] spiralOrder (int [][] matrix ) {
74
- int m, n;
75
- if (matrix == null || (m = matrix. length) == 0 || matrix[0 ] == null
76
- || (n = matrix[0 ]. length) == 0 )
94
+ if (matrix. length == 0 || matrix[0 ]. length == 0 ) {
77
95
return new int [] {};
78
- res = new int [m * n];
79
- index = 0 ;
80
- int i1 = 0 , i2 = m - 1 ;
81
- int j1 = 0 , j2 = n - 1 ;
82
- while (i1 <= i2 && j1 <= j2) {
83
- add(matrix, i1++ , j1++ , i2-- , j2-- );
84
96
}
85
- return res;
97
+ int m = matrix. length, n = matrix[0 ]. length;
98
+ boolean [][] vis = new boolean [m][n];
99
+ int [] ans = new int [m * n];
100
+ int i = 0 , j = 0 , k = 0 ;
101
+ int [] dirs = {0 , 1 , 0 , - 1 , 0 };
102
+ for (int h = 0 ; h < m * n; ++ h) {
103
+ ans[h] = matrix[i][j];
104
+ vis[i][j] = true ;
105
+ int x = i + dirs[k], y = j + dirs[k + 1 ];
106
+ if (x < 0 || y < 0 || x >= m || y >= n || vis[x][y]) {
107
+ k = (k + 1 ) % 4 ;
108
+ x = i + dirs[k];
109
+ y = j + dirs[k + 1 ];
110
+ }
111
+ i = x;
112
+ j = y;
113
+ }
114
+ return ans;
86
115
}
116
+ }
117
+ ```
87
118
88
- private void add (int [][] matrix , int i1 , int j1 , int i2 , int j2 ) {
89
- if (i1 == i2) {
90
- for (int j = j1; j <= j2; ++ j) {
91
- res[index++ ] = matrix[i1][j];
92
- }
93
- return ;
119
+ ``` java
120
+ class Solution {
121
+ public int [] spiralOrder (int [][] matrix ) {
122
+ if (matrix. length == 0 || matrix[0 ]. length == 0 ) {
123
+ return new int [] {};
94
124
}
95
- if (j1 == j2) {
96
- for (int i = i1; i <= i2; ++ i) {
97
- res[index++ ] = matrix[i][j1];
125
+ int m = matrix. length, n = matrix[0 ]. length;
126
+ int top = 0 , bottom = m - 1 , left = 0 , right = n - 1 ;
127
+ int [] ans = new int [m * n];
128
+ int k = 0 ;
129
+ while (left <= right && top <= bottom) {
130
+ for (int j = left; j <= right; ++ j) {
131
+ ans[k++ ] = matrix[top][j];
98
132
}
99
- return ;
100
- }
101
- for (int j = j1; j < j2; ++ j) {
102
- res[index++ ] = matrix[i1][j];
103
- }
104
- for (int i = i1; i < i2; ++ i) {
105
- res[index++ ] = matrix[i][j2];
106
- }
107
- for (int j = j2; j > j1; -- j) {
108
- res[index++ ] = matrix[i2][j];
109
- }
110
- for (int i = i2; i > i1; -- i) {
111
- res[index++ ] = matrix[i][j1];
133
+ for (int i = top + 1 ; i <= bottom; ++ i) {
134
+ ans[k++ ] = matrix[i][right];
135
+ }
136
+ if (left < right && top < bottom) {
137
+ for (int j = right - 1 ; j >= left; -- j) {
138
+ ans[k++ ] = matrix[bottom][j];
139
+ }
140
+ for (int i = bottom - 1 ; i > top; -- i) {
141
+ ans[k++ ] = matrix[i][left];
142
+ }
143
+ }
144
+ ++ top;
145
+ -- bottom;
146
+ ++ left;
147
+ -- right;
112
148
}
149
+ return ans;
113
150
}
114
151
}
115
152
```
@@ -120,37 +157,122 @@ class Solution {
120
157
class Solution {
121
158
public:
122
159
vector<int > spiralOrder(vector<vector<int >>& matrix) {
160
+ if (matrix.size() == 0 || matrix[ 0] .size() == 0) {
161
+ return {};
162
+ }
163
+ int m = matrix.size(), n = matrix[ 0] .size();
164
+ bool vis[ m] [ n ] ;
165
+ memset(vis, false, sizeof vis);
166
+ int i = 0, j = 0, k = 0;
167
+ int dirs[ 5] = {0, 1, 0, -1, 0};
168
+ vector<int > ans(m * n);
169
+ for (int h = 0; h < m * n; ++h) {
170
+ ans[ h] = matrix[ i] [ j ] ;
171
+ vis[ i] [ j ] = true;
172
+ int x = i + dirs[ k] , y = j + dirs[ k + 1] ;
173
+ if (x < 0 || y < 0 || x >= m || y >= n || vis[ x] [ y ] ) {
174
+ k = (k + 1) % 4;
175
+ x = i + dirs[ k] ;
176
+ y = j + dirs[ k + 1] ;
177
+ }
178
+ i = x;
179
+ j = y;
180
+ }
181
+ return ans;
182
+ }
183
+ };
184
+ ```
185
+
186
+ ```cpp
187
+ class Solution {
188
+ public:
189
+ vector<int> spiralOrder(vector<vector<int>>& matrix) {
190
+ if (matrix.size() == 0 || matrix[0].size() == 0) {
191
+ return {};
192
+ }
193
+ int m = matrix.size(), n = matrix[0].size();
194
+ int top = 0, bottom = m - 1, left = 0, right = n - 1;
123
195
vector<int> ans;
124
- if (matrix.size() == 0)
125
- return ans;
126
- int left = 0, top = 0, bottom = matrix.size() - 1, right = matrix[ 0] .size() - 1;
127
- while (true) {
128
- for (int i = left; i <= right; i++)
129
- ans.push_back(matrix[ top] [ i ] );
130
- top++;
131
- if (top > bottom)
132
- break;
133
- for (int i = top; i <= bottom; i++)
134
- ans.push_back(matrix[ i] [ right ] );
135
- right--;
136
- if (right < left)
137
- break;
138
- for (int i = right; i >= left; i--)
139
- ans.push_back(matrix[ bottom] [ i ] );
140
- bottom--;
141
- if (bottom < top)
142
- break;
143
- for (int i = bottom; i >= top; i--)
144
- ans.push_back(matrix[ i] [ left ] );
145
- left++;
146
- if (left > right)
147
- break;
196
+ while (top <= bottom && left <= right) {
197
+ for (int j = left; j <= right; ++j) ans.push_back(matrix[top][j]);
198
+ for (int i = top + 1; i <= bottom; ++i) ans.push_back(matrix[i][right]);
199
+ if (left < right && top < bottom) {
200
+ for (int j = right - 1; j >= left; --j) ans.push_back(matrix[bottom][j]);
201
+ for (int i = bottom - 1; i > top; --i) ans.push_back(matrix[i][left]);
202
+ }
203
+ ++top;
204
+ --bottom;
205
+ ++left;
206
+ --right;
148
207
}
149
208
return ans;
150
209
}
151
210
};
152
211
```
153
212
213
+ ### ** Go**
214
+
215
+ ``` go
216
+ func spiralOrder (matrix [][]int ) []int {
217
+ if len (matrix) == 0 || len (matrix[0 ]) == 0 {
218
+ return []int {}
219
+ }
220
+ m , n := len (matrix), len (matrix[0 ])
221
+ vis := make ([][]bool , m)
222
+ for i := range vis {
223
+ vis[i] = make ([]bool , n)
224
+ }
225
+ i , j , k := 0 , 0 , 0
226
+ dirs := [5 ]int {0 , 1 , 0 , -1 , 0 }
227
+ ans := make ([]int , m*n)
228
+ for h := 0 ; h < m*n; h++ {
229
+ ans[h] = matrix[i][j]
230
+ vis[i][j] = true
231
+ x , y := i+dirs[k], j+dirs[k+1 ]
232
+ if x < 0 || y < 0 || x >= m || y >= n || vis[x][y] {
233
+ k = (k + 1 ) % 4
234
+ x, y = i+dirs[k], j+dirs[k+1 ]
235
+ }
236
+ i, j = x, y
237
+ }
238
+ return ans
239
+ }
240
+ ```
241
+
242
+ ``` go
243
+ func spiralOrder (matrix [][]int ) []int {
244
+ if len (matrix) == 0 || len (matrix[0 ]) == 0 {
245
+ return []int {}
246
+ }
247
+ m , n := len (matrix), len (matrix[0 ])
248
+ ans := make ([]int , 0 , m*n)
249
+
250
+ top , bottom , left , right := 0 , m-1 , 0 , n-1
251
+ for left <= right && top <= bottom {
252
+ for i := left; i <= right; i++ {
253
+ ans = append (ans, matrix[top][i])
254
+ }
255
+ for i := top + 1 ; i <= bottom; i++ {
256
+ ans = append (ans, matrix[i][right])
257
+ }
258
+ if left < right && top < bottom {
259
+ for i := right - 1 ; i >= left; i-- {
260
+ ans = append (ans, matrix[bottom][i])
261
+ }
262
+ for i := bottom - 1 ; i > top; i-- {
263
+ ans = append (ans, matrix[i][left])
264
+ }
265
+ }
266
+ top++
267
+ bottom--
268
+ left++
269
+ right--
270
+ }
271
+
272
+ return ans
273
+ }
274
+ ```
275
+
154
276
### ** JavaScript**
155
277
156
278
``` js
@@ -159,51 +281,31 @@ public:
159
281
* @return {number[]}
160
282
*/
161
283
var spiralOrder = function (matrix ) {
162
- if (!matrix || !matrix.length) return [];
163
- let row = matrix.length;
164
- let col = matrix[0].length;
165
- let res = [];
166
- let moves = {
167
- right: [0, 1],
168
- down: [1, 0],
169
- left: [0, -1],
170
- up: [-1, 0],
171
- };
172
- let k = 0;
173
- function dfs(i, j, dir) {
174
- if (
175
- i < 0 ||
176
- j < 0 ||
177
- i >= row ||
178
- j >= col ||
179
- res.length === row * col
180
- ) {
181
- return;
284
+ const ans = [];
285
+ if (matrix .length == 0 || matrix[0 ].length == 0 ) {
286
+ return ans;
287
+ }
288
+ const m = matrix .length ;
289
+ const n = matrix[0 ].length ;
290
+ let [top, bottom, left, right] = [0 , m - 1 , 0 , n - 1 ];
291
+ while (top <= bottom && left <= right) {
292
+ for (let j = left; j <= right; ++ j) {
293
+ ans .push (matrix[top][j]);
182
294
}
183
- res.push(matrix[i][j]);
184
- switch (dir) {
185
- case 'right':
186
- if (j === col - 1 - k) dir = 'down';
187
- break;
188
- case 'down':
189
- if (i === row - 1 - k) dir = 'left';
190
- break;
191
- case 'left':
192
- if (j === k) {
193
- dir = 'up';
194
- k++;
195
- }
196
- break;
197
- case 'up':
198
- if (i === k) dir = 'right';
199
- break;
295
+ for (let i = top + 1 ; i <= bottom; ++ i) {
296
+ ans .push (matrix[i][right]);
297
+ }
298
+ if (left < right && top < bottom) {
299
+ for (let j = right - 1 ; j >= left; -- j) {
300
+ ans .push (matrix[bottom][j]);
301
+ }
302
+ for (let i = bottom - 1 ; i > top; -- i) {
303
+ ans .push (matrix[i][left]);
304
+ }
200
305
}
201
- let x = i + moves[dir][0];
202
- let y = j + moves[dir][1];
203
- dfs(x, y, dir);
306
+ [top, bottom, left, right] = [top + 1 , bottom - 1 , left + 1 , right - 1 ];
204
307
}
205
- dfs(0, 0, 'right');
206
- return res;
308
+ return ans;
207
309
};
208
310
```
209
311
0 commit comments