forked from youngyangyang04/leetcode-master
-
Notifications
You must be signed in to change notification settings - Fork 0
[pull] master from youngyangyang04:master #76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
a8d3874
添加0053.最大子序和(动态规划)空间复杂度为O(1)的解法 Java版本
YunChenCloud 7122ee5
Merge pull request #1612 from YunChenCloud/master
youngyangyang04 ca4f55a
Update
youngyangyang04 697b8ac
Merge branch 'master' of github.com:youngyangyang04/leetcode-master
youngyangyang04 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
80 changes: 80 additions & 0 deletions
problems/0130.被围绕的区域.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
|
||
# 130. 被围绕的区域 | ||
|
||
[题目链接](https://leetcode.cn/problems/surrounded-regions/) | ||
|
||
给你一个 m x n 的矩阵 board ,由若干字符 'X' 和 'O' ,找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。 | ||
|
||
 | ||
|
||
* 输入:board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]] | ||
* 输出:[["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]] | ||
* 解释:被围绕的区间不会存在于边界上,换句话说,任何边界上的 'O' 都不会被填充为 'X'。 任何不在边界上,或不与边界上的 'O' 相连的 'O' 最终都会被填充为 'X'。如果两个元素在水平或垂直方向相邻,则称它们是"相连"的。 | ||
|
||
## 思路 | ||
|
||
这道题目和1020. 飞地的数量正好反过来了,[1020. 飞地的数量](https://leetcode.cn/problems/number-of-enclaves/solution/by-carlsun-2-7lt9/)是求 地图中间的空格数,而本题是要把地图中间的'O'都改成'X'。 | ||
|
||
那么两题在思路上也是差不多的。 | ||
|
||
依然是从地图周边出发,将周边空格相邻的'O'都做上标记,然后在遍历一遍地图,遇到 'O' 且没做过标记的,那么都是地图中间的'O',全部改成'X'就行。 | ||
|
||
有的录友可能想,我在定义一个 visited 二维数组,单独标记周边的'O',然后遍历地图的时候同时对 数组board 和 数组visited 进行判断,是否'O'改成'X'。 | ||
|
||
这样做其实就有点麻烦了,不用额外定义空间了,标记周边的'O',可以直接改board的数值为其他特殊值。 | ||
|
||
步骤一:深搜或者广搜将地图周边的'O'全部改成'A',如图所示: | ||
|
||
 | ||
|
||
步骤二:在遍历地图,将'O'全部改成'X'(地图中间的'O'改成了'X'),将'A'改回'O'(保留的地图周边的'O'),如图所示: | ||
|
||
 | ||
|
||
整体C++代码如下,以下使用dfs实现,其实遍历方式dfs,bfs都是可以的。 | ||
|
||
```CPP | ||
class Solution { | ||
private: | ||
int dir[4][2] = {-1, 0, 0, -1, 1, 0, 0, 1}; // 保存四个方向 | ||
void dfs(vector<vector<char>>& board, int x, int y) { | ||
board[x][y] = 'A'; | ||
for (int i = 0; i < 4; i++) { // 向四个方向遍历 | ||
int nextx = x + dir[i][0]; | ||
int nexty = y + dir[i][1]; | ||
// 超过边界 | ||
if (nextx < 0 || nextx >= board.size() || nexty < 0 || nexty >= board[0].size()) continue; | ||
// 不符合条件,不继续遍历 | ||
if (board[nextx][nexty] == 'X' || board[nextx][nexty] == 'A') continue; | ||
dfs (board, nextx, nexty); | ||
} | ||
return; | ||
} | ||
|
||
public: | ||
void solve(vector<vector<char>>& board) { | ||
int n = board.size(), m = board[0].size(); | ||
// 步骤一: | ||
// 从左侧边,和右侧边 向中间遍历 | ||
for (int i = 0; i < n; i++) { | ||
if (board[i][0] == 'O') dfs(board, i, 0); | ||
if (board[i][m - 1] == 'O') dfs(board, i, m - 1); | ||
} | ||
|
||
// 从上边和下边 向中间遍历 | ||
for (int j = 0; j < m; j++) { | ||
if (board[0][j] == 'O') dfs(board, 0, j); | ||
if (board[n - 1][j] == 'O') dfs(board, n - 1, j); | ||
} | ||
// 步骤二: | ||
for (int i = 0; i < n; i++) { | ||
for (int j = 0; j < m; j++) { | ||
if (board[i][j] == 'O') board[i][j] = 'X'; | ||
if (board[i][j] == 'A') board[i][j] = 'O'; | ||
} | ||
} | ||
} | ||
}; | ||
``` | ||
|
||
## 其他语言版本 |
146 changes: 146 additions & 0 deletions
problems/0200.岛屿数量.广搜版.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
|
||
|
||
# 200. 岛屿数量 | ||
|
||
[题目链接](https://leetcode.cn/problems/number-of-islands/) | ||
|
||
给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。 | ||
|
||
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 | ||
|
||
此外,你可以假设该网格的四条边均被水包围。 | ||
|
||
 | ||
|
||
提示: | ||
|
||
* m == grid.length | ||
* n == grid[i].length | ||
* 1 <= m, n <= 300 | ||
* grid[i][j] 的值为 '0' 或 '1' | ||
|
||
## 思路 | ||
|
||
注意题目中每座岛屿只能由**水平方向和/或竖直方向上**相邻的陆地连接形成。 | ||
|
||
也就是说斜角度链接是不算了, 例如示例二,是三个岛屿,如图: | ||
|
||
 | ||
|
||
这道题题目是 DFS,BFS,并查集,基础题目。 | ||
|
||
本题思路,是用遇到一个没有遍历过的节点陆地,计数器就加一,然后把该节点陆地所能遍历到的陆地都标记上。 | ||
|
||
在遇到标记过的陆地节点和海洋节点的时候直接跳过。 这样计数器就是最终岛屿的数量。 | ||
|
||
那么如果把节点陆地所能遍历到的陆地都标记上呢,就可以使用 DFS,BFS或者并查集。 | ||
|
||
### 广度优先搜索 | ||
|
||
不少同学用广搜做这道题目的时候,超时了。 这里有一个广搜中很重要的细节: | ||
|
||
根本原因是**只要 加入队列就代表 走过,就需要标记,而不是从队列拿出来的时候再去标记走过**。 | ||
|
||
很多同学可能感觉这有区别吗? | ||
|
||
如果从队列拿出节点,再去标记这个节点走过,就会发生下图所示的结果,会导致很多节点重复加入队列。 | ||
|
||
 | ||
|
||
超时写法 (从队列中取出节点再标记) | ||
|
||
```CPP | ||
int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1}; // 四个方向 | ||
void bfs(vector<vector<char>>& grid, vector<vector<bool>>& visited, int x, int y) { | ||
queue<pair<int, int>> que; | ||
que.push({x, y}); | ||
while(!que.empty()) { | ||
pair<int ,int> cur = que.front(); que.pop(); | ||
int curx = cur.first; | ||
int cury = cur.second; | ||
visited[curx][cury] = true; // 从队列中取出在标记走过 | ||
for (int i = 0; i < 4; i++) { | ||
int nextx = curx + dir[i][0]; | ||
int nexty = cury + dir[i][1]; | ||
if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue; // 越界了,直接跳过 | ||
if (!visited[nextx][nexty] && grid[nextx][nexty] == '1') { | ||
que.push({nextx, nexty}); | ||
} | ||
} | ||
} | ||
|
||
} | ||
``` | ||
|
||
加入队列 就代表走过,立刻标记,正确写法: | ||
|
||
```CPP | ||
int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1}; // 四个方向 | ||
void bfs(vector<vector<char>>& grid, vector<vector<bool>>& visited, int x, int y) { | ||
queue<pair<int, int>> que; | ||
que.push({x, y}); | ||
visited[x][y] = true; // 只要加入队列,立刻标记 | ||
while(!que.empty()) { | ||
pair<int ,int> cur = que.front(); que.pop(); | ||
int curx = cur.first; | ||
int cury = cur.second; | ||
for (int i = 0; i < 4; i++) { | ||
int nextx = curx + dir[i][0]; | ||
int nexty = cury + dir[i][1]; | ||
if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue; // 越界了,直接跳过 | ||
if (!visited[nextx][nexty] && grid[nextx][nexty] == '1') { | ||
que.push({nextx, nexty}); | ||
visited[nextx][nexty] = true; // 只要加入队列立刻标记 | ||
} | ||
} | ||
} | ||
|
||
} | ||
``` | ||
|
||
以上两个版本其实,其实只有细微区别,就是 `visited[x][y] = true;` 放在的地方,着去取决于我们对 代码中队列的定义,队列中的节点就表示已经走过的节点。 **所以只要加入队列,理解标记该节点走过**。 | ||
|
||
本题完整广搜代码: | ||
|
||
```CPP | ||
class Solution { | ||
private: | ||
int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1}; // 四个方向 | ||
void bfs(vector<vector<char>>& grid, vector<vector<bool>>& visited, int x, int y) { | ||
queue<pair<int, int>> que; | ||
que.push({x, y}); | ||
visited[x][y] = true; // 只要加入队列,立刻标记 | ||
while(!que.empty()) { | ||
pair<int ,int> cur = que.front(); que.pop(); | ||
int curx = cur.first; | ||
int cury = cur.second; | ||
for (int i = 0; i < 4; i++) { | ||
int nextx = curx + dir[i][0]; | ||
int nexty = cury + dir[i][1]; | ||
if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue; // 越界了,直接跳过 | ||
if (!visited[nextx][nexty] && grid[nextx][nexty] == '1') { | ||
que.push({nextx, nexty}); | ||
visited[nextx][nexty] = true; // 只要加入队列立刻标记 | ||
} | ||
} | ||
} | ||
} | ||
public: | ||
int numIslands(vector<vector<char>>& grid) { | ||
int n = grid.size(), m = grid[0].size(); | ||
vector<vector<bool>> visited = vector<vector<bool>>(n, vector<bool>(m, false)); | ||
|
||
int result = 0; | ||
for (int i = 0; i < n; i++) { | ||
for (int j = 0; j < m; j++) { | ||
if (!visited[i][j] && grid[i][j] == '1') { | ||
result++; // 遇到没访问过的陆地,+1 | ||
bfs(grid, visited, i, j); // 将与其链接的陆地都标记上 true | ||
} | ||
} | ||
} | ||
return result; | ||
} | ||
}; | ||
|
||
``` |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.