Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f8b6f08

Browse files
update md files
1 parent a847b5a commit f8b6f08

File tree

4 files changed

+684
-0
lines changed

4 files changed

+684
-0
lines changed
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
2+
3+
# 54_SpiralMatrix_螺旋矩阵
4+
5+
## 📌题目详情
6+
7+
[leetcode 题目地址](https://leetcode.com/problems/spiral-matrix/)
8+
9+
[leetcode-cn 题目地址](https://leetcode-cn.com/problems/spiral-matrix/)
10+
11+
📗Difficulty:**Medium**
12+
13+
🎯Tags:
14+
15+
+ **[Array](https://leetcode-cn.com/tag/array/)**
16+
17+
18+
19+
---
20+
21+
## 📃题目描述
22+
23+
给定一个包含 `m x n` 个元素的矩阵(`m` 行, `n` 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
24+
25+
**样例 1:**
26+
27+
```
28+
输入:
29+
[
30+
[ 1, 2, 3 ],
31+
[ 4, 5, 6 ],
32+
[ 7, 8, 9 ]
33+
]
34+
输出: [1,2,3,6,9,8,7,4,5]
35+
```
36+
37+
38+
39+
**样例 2:**
40+
41+
```
42+
输入:
43+
[
44+
[1, 2, 3, 4],
45+
[5, 6, 7, 8],
46+
[9,10,11,12]
47+
]
48+
输出: [1,2,3,4,8,12,11,10,9,5,6,7]
49+
```
50+
51+
52+
53+
****
54+
55+
## 🏹🎯解题思路
56+
57+
58+
类似的题目还有,《蛇形填数》。类似于贪吃蛇,只能有 四个方向去移动,而且不能超越一定的范围。
59+
60+
这类题目,称其为**"模拟题"**,就是说,本题的解题过程是模拟人工解决这类问题的过程,并不涉及到很复杂的数据结构和算法。
61+
62+
63+
64+
首先,观察填数的顺序。从左上角开始,然后向右到边界,再向下,再向上,再向右边。**变换 4 次方向。**
65+
66+
!["蛇头"变换过程](https://assets.ryantech.ltd/20200605135753.jpg)
67+
68+
其中一个疑问在,如何在变换方向后确定"折返点"?
69+
70+
对于外圈的点位来说,可以判断是否越界。但是对于内圈的点位,必须要有个指示的东西,否则会重复走走过的路,造成 bug 。
71+
72+
而对于越界的判断有 2 种思路:
73+
74+
+ 先污染,后治理。
75+
+ 不污染,向后看一个。
76+
77+
下面给出这 2 种思路的代码。
78+
79+
### 先污染,后治理
80+
81+
82+
设置一个和输入矩阵等大的矩阵,其中每个元素的初始值为 0,代表原始矩阵相应位置没有被访问过。
83+
84+
每次访问过该位置后,将该位置的值写为 1,代表该位置的元素被访问过。如果遇到该位置元素被访问了,那么就"撞南墙",改变方向。直到每个元素被访问到。
85+
86+
87+
88+
89+
#### 代码实现
90+
91+
```java
92+
public List<Integer> spiralOrder(int[][] matrix) {
93+
if (matrix.length == 0) {
94+
return new LinkedList<>();
95+
}
96+
97+
int row = matrix.length;
98+
int column = matrix[0].length;
99+
int resSize = row * column;
100+
int[][] visited = new int[row][column];
101+
List<Integer> ans = new LinkedList<>();
102+
int x = 0;
103+
int y = 0;
104+
int tot = 0;
105+
while (tot < resSize) {
106+
while (y < column && visited[x][y] == 0) {
107+
visited[x][y] = 1;
108+
ans.add(matrix[x][y]);
109+
tot++;
110+
y++;
111+
}
112+
y--; // 修正
113+
x++; // 换到下一行
114+
while (x < row && visited[x][y] == 0) {
115+
visited[x][y] = 1;
116+
ans.add(matrix[x][y]);
117+
tot++;
118+
x++;
119+
}
120+
x--; // 修正
121+
y--; // 换行
122+
while (y >= 0 && visited[x][y] == 0) {
123+
visited[x][y] = 1;
124+
ans.add(matrix[x][y]);
125+
tot++;
126+
y--;
127+
}
128+
y++; // 修正
129+
x--; // 换行
130+
while (x >= 0 && visited[x][y] == 0) {
131+
visited[x][y] = 1;
132+
ans.add(matrix[x][y]);
133+
tot++;
134+
x--;
135+
}
136+
x++; // 修正
137+
y++; // 换行
138+
}
139+
return ans;
140+
}
141+
```
142+
143+
144+
145+
#### 复杂度分析
146+
147+
+ 时间复杂度: `O(n)` 。每个元素都被访问一次。
148+
+ 空间复杂度: `O(n)` 。需要设置一个和输入数组等大的数组来标记元素是否被访问过。
149+
150+
151+
152+
### 向后看一步,精准卡位
153+
154+
先检查此位置是否越界,代码更加简洁清晰。
155+
156+
157+
158+
#### 代码实现
159+
160+
```java
161+
public List<Integer> spiralOrder(int[][] matrix) {
162+
if (matrix.length == 0) {
163+
return new LinkedList<>();
164+
}
165+
166+
int row = matrix.length;
167+
int column = matrix[0].length;
168+
int resSize = row * column;
169+
int[][] visited = new int[row][column];
170+
List<Integer> ans = new LinkedList<>();
171+
int x = 0;
172+
int y = 0;
173+
int tot = 1;
174+
ans.add(matrix[x][y]);
175+
visited[x][y] = 1;
176+
while (tot < resSize) {
177+
while (y + 1 < column && visited[x][y + 1] == 0) {
178+
visited[x][++y] = 1;
179+
ans.add(matrix[x][y]);
180+
tot++;
181+
}
182+
while (x + 1 < row && visited[x + 1][y] == 0) {
183+
visited[++x][y] = 1;
184+
ans.add(matrix[x][y]);
185+
tot++;
186+
}
187+
while (y - 1 >= 0 && visited[x][y - 1] == 0) {
188+
visited[x][--y] = 1;
189+
ans.add(matrix[x][y]);
190+
tot++;
191+
}
192+
while (x - 1 >= 0 && visited[x - 1][y] == 0) {
193+
visited[--x][y] = 1;
194+
ans.add(matrix[x][y]);
195+
tot++;
196+
}
197+
}
198+
return ans;
199+
}
200+
```
201+
202+
203+
204+
#### 复杂度分析
205+
206+
+ 时间复杂度: `O(n)` 。每个元素都被访问一次。
207+
+ 空间复杂度: `O(n)` 。需要设置一个和输入数组等大的数组来标记元素是否被访问过。
208+
209+
210+
211+
## 💡总结
212+
213+
### 相似题目
214+
215+
[59. 螺旋矩阵 II](https://leetcode-cn.com/problems/spiral-matrix-ii/)
216+
217+
[面试题29. 顺时针打印矩阵](https://leetcode-cn.com/problems/shun-shi-zhen-da-yin-ju-zhen-lcof/)
218+
219+
220+
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
2+
3+
# 54_SpiralMatrix_螺旋矩阵 2
4+
5+
## 📌题目详情
6+
7+
[leetcode 题目地址](https://leetcode.com/problems/spiral-matrix-ii/)
8+
9+
[leetcode-cn 题目地址](https://leetcode-cn.com/problems/spiral-matrix-ii/)
10+
11+
📗Difficulty:**Medium**
12+
13+
🎯Tags:
14+
15+
+ **[Array](https://leetcode-cn.com/tag/array/)**
16+
17+
18+
19+
---
20+
21+
## 📃题目描述
22+
23+
给定一个正整数 `n`,生成一个包含 1 到 `n^2` 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
24+
25+
**样例 1:**
26+
27+
```
28+
输入: 3
29+
输出:
30+
[
31+
[ 1, 2, 3 ],
32+
[ 8, 9, 4 ],
33+
[ 7, 6, 5 ]
34+
]
35+
```
36+
37+
38+
39+
****
40+
41+
## 🏹🎯解题思路
42+
43+
44+
类似的题目还有,《蛇形填数》。类似于贪吃蛇,只能有 四个方向去移动,而且不能超越一定的范围。
45+
46+
这类题目,称其为**"模拟题"**,就是说,本题的解题过程是模拟人工解决这类问题的过程,并不涉及到很复杂的数据结构和算法。
47+
48+
49+
50+
首先,观察填数的顺序。从左上角开始,然后向右到边界,再向下,再向上,再向右边。**变换 4 次方向。**
51+
52+
!["蛇头"变换过程](https://assets.ryantech.ltd/20200605135753.jpg)
53+
54+
其中一个疑问在,如何在变换方向后确定"折返点"?
55+
56+
对于外圈的点位来说,可以判断是否越界。但是对于内圈的点位,必须要有个指示的东西,否则会重复走走过的路,造成 bug 。
57+
58+
而对于越界的判断有 2 种思路:
59+
60+
+ 先污染,后治理。
61+
+ 不污染,向后看一个。
62+
63+
下面给出第 2 种思路的代码。
64+
65+
66+
67+
### 向后看一步,精准卡位
68+
69+
先检查此位置是否越界,代码更加简洁清晰。
70+
71+
72+
73+
#### 代码实现
74+
75+
```java
76+
public int[][] generateMatrix(int n) {
77+
if (n <= 0) {
78+
return new int[][]{};
79+
}
80+
81+
int[][] ans = new int[n][n];
82+
int tot = 1;
83+
int row = 0;
84+
int column = 0;
85+
ans[row][column] = tot;
86+
while (tot < n * n) {
87+
while (column + 1 < n && ans[row][column + 1] == 0) {
88+
ans[row][++column] = ++tot;
89+
}
90+
while (row + 1 < n && ans[row + 1][column] == 0) {
91+
ans[++row][column] = ++tot;
92+
}
93+
while (column - 1 >= 0 && ans[row][column - 1] == 0) {
94+
ans[row][--column] = ++tot;
95+
}
96+
while (row - 1 >= 0 && ans[row - 1][column] == 0) {
97+
ans[--row][column] = ++tot;
98+
}
99+
}
100+
return ans;
101+
}
102+
```
103+
104+
105+
106+
#### 复杂度分析
107+
108+
+ 时间复杂度: `O(n)` 。每个元素都被访问一次。
109+
+ 空间复杂度: `O(n)` 。需要设置一个和输入数组等大的数组来标记元素是否被访问过。
110+
111+
112+
113+
## 💡总结
114+
115+
### 相似题目
116+
117+
[54. 螺旋矩阵](https://leetcode-cn.com/problems/spiral-matrix/)
118+
119+
[面试题29. 顺时针打印矩阵](https://leetcode-cn.com/problems/shun-shi-zhen-da-yin-ju-zhen-lcof/)
120+
121+
122+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /