Skip to content

Commit 86abbc9

Browse files
committed
feat: add solutions to lc problem: No.29
1 parent f3f5f7f commit 86abbc9

File tree

6 files changed

+322
-239
lines changed

6 files changed

+322
-239
lines changed

lcof/面试题29. 顺时针打印矩阵/README.md

+220-118
Original file line numberDiff line numberDiff line change
@@ -31,85 +31,122 @@
3131

3232
## 解法
3333

34+
**方法一:模拟**
35+
36+
我们用 $i$ 和 $j$ 分别表示当前访问到的元素的行和列,用 $k$ 表示当前的方向,用数组或哈希表 $vis$ 记录每个元素是否被访问过。每次我们访问到一个元素后,将其标记为已访问,然后按照当前的方向前进一步,如果前进一步后发现越界或者已经访问过,则改变方向继续前进,直到遍历完整个矩阵。
37+
38+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。
39+
40+
**方法二:逐层模拟**
41+
3442
从外往里一圈一圈遍历并存储矩阵元素即可。
3543

44+
时间复杂度 $O(m \times n)$,空间复杂度 $O(1)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。
45+
3646
<!-- tabs:start -->
3747

3848
### **Python3**
3949

4050
```python
4151
class Solution:
4252
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+
```
5470

71+
```python
72+
class Solution:
73+
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
5574
if not matrix or not matrix[0]:
5675
return []
5776
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
6487
```
6588

6689
### **Java**
6790

6891
```java
6992
class Solution {
70-
private int[] res;
71-
private int index;
72-
7393
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) {
7795
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--);
8496
}
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;
86115
}
116+
}
117+
```
87118

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[] {};
94124
}
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];
98132
}
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;
112148
}
149+
return ans;
113150
}
114151
}
115152
```
@@ -120,37 +157,122 @@ class Solution {
120157
class Solution {
121158
public:
122159
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;
123195
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;
148207
}
149208
return ans;
150209
}
151210
};
152211
```
153212

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+
154276
### **JavaScript**
155277

156278
```js
@@ -159,51 +281,31 @@ public:
159281
* @return {number[]}
160282
*/
161283
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]);
182294
}
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+
}
200305
}
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];
204307
}
205-
dfs(0, 0, 'right');
206-
return res;
308+
return ans;
207309
};
208310
```
209311

0 commit comments

Comments
 (0)