-
Notifications
You must be signed in to change notification settings - Fork 0
200. Number of Islands #36
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ## 問題: [200. Number of Islands](https://leetcode.com/problems/number-of-islands/description/) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| # Step 1 | ||
|
|
||
| - 各セルで条件を満たす場合、dfsを行う | ||
| - dfs | ||
| - セルが1、まだ訪れていない、かつ範囲内だったら、counterを1増やして上下左右に行き、次のセルでも同じことを繰り返す | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def numIslands(self, grid: List[List[str]]) -> int: | ||
| rows = len(grid) | ||
| columns = len(grid[0]) | ||
| visited = set() | ||
| num_islands = 0 | ||
|
|
||
| def dfs(r, c): | ||
| if (r, c) not in visited and r >= 0 and r < rows and c >= 0 and c < columns and grid[r][c] == "1": | ||
| visited.add((r, c)) | ||
| dfs(r + 1, c) | ||
| dfs(r - 1, c) | ||
| dfs(r, c + 1) | ||
| dfs(r, c - 1) | ||
|
|
||
| for r in range(rows): | ||
| for c in range(columns): | ||
| if grid[r][c] == "1" and (r, c) not in visited: | ||
| num_islands += 1 | ||
| dfs(r, c) | ||
|
|
||
| return num_islands | ||
| ``` | ||
|
|
||
| 時間計算量: $O(mn)$ | ||
|
|
||
| 空間計算量: $O(mn)$ | ||
|
|
||
| アルゴリズム最大実行時間(概算): 時間計算量 / Pythonの1秒あたりの計算ステップ数 -> $(300 \times 300) \div 10,000,000 = 0.001 (s)$ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # Step 2 | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def numIslands(self, grid: List[List[str]]) -> int: | ||
| rows = len(grid) | ||
| columns = len(grid[0]) | ||
| directions = [[1, 0], [-1, 0], [0, 1], [0, -1]] | ||
| visited = set() | ||
| num_islands = 0 | ||
|
|
||
| def dfs(r, c): | ||
| if not (0 <= r < rows and 0 <= c < columns): | ||
| return | ||
| if grid[r][c] != "1" or (r, c) in visited: | ||
| return | ||
| visited.add((r, c)) | ||
| for dr, dc in directions: | ||
| dfs(r + dr, c + dc) | ||
|
|
||
| for r in range(rows): | ||
| for c in range(columns): | ||
| if grid[r][c] == "1" and (r, c) not in visited: | ||
| num_islands += 1 | ||
| dfs(r, c) | ||
|
|
||
| return num_islands | ||
| ``` | ||
|
|
||
| 時間計算量: $O(mn)$ | ||
|
|
||
| 空間計算量: $O(mn)$ | ||
|
|
||
| アルゴリズム最大実行時間(概算): 時間計算量 / Pythonの1秒あたりの計算ステップ数 -> $(300 \times 300) \div 10,000,000 = 0.001 (s)$ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| # Step 3 | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def numIslands(self, grid: List[List[str]]) -> int: | ||
| rows = len(grid) | ||
| columns = len(grid[0]) | ||
| directions = [[1, 0], [-1, 0], [0, 1], [0, -1]] | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 後から変更しない immutable な値であることを明示する目的で、tuple にしてもいいかもしれません。好みの範囲だと思いますが。 |
||
| visited = set() | ||
| num_islands = 0 | ||
|
|
||
| def dfs(r, c): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dfs という関数名はあまり好まれないように思います。DFSという内部でとっているアプローチを説明するよりも、何をするのか、何を入れて何が返ってくるのかわかりやすい関数名の方が呼び出し側からしたら扱いやすいと思います。 |
||
| if not (0 <= r < rows and 0 <= c < columns): | ||
| return | ||
| if grid[r][c] != "1" or (r, c) in visited: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 個人的な好みですが (個人的な好みばかりですみません、サンプルの一つとして) 一つの行で複数のことをするのは少し気を抜くと複雑になりすぎてしまうので、一行では基本的に一つのことがしたいです。この条件、「島ではない」と「訪問済み」を含んでいますが、早期リターンをするのは共通していますが、確認している条件は独立しているように思います。(好みの範囲だと思います。) |
||
| return | ||
| visited.add((r, c)) | ||
| for dr, dc in directions: | ||
| dfs(r + dr, c + dc) | ||
|
|
||
| for r in range(rows): | ||
| for c in range(columns): | ||
| if grid[r][c] == "1" and (r, c) not in visited: | ||
| num_islands += 1 | ||
| dfs(r, c) | ||
|
|
||
| return num_islands | ||
| ``` | ||
| 1回目: 5分 9秒 | ||
|
|
||
| 2回目: 3分 25秒 | ||
|
|
||
| 3回目: 2分 57秒 | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rows だと、row の集まりのSequenceか何かだという印象が個人的にはあるので、
num_rowsなどとした方が row の数であることが明確になるかもしれません。