From f30b56fa117d0d849f513ed0f0bfd74bd5a4c70c Mon Sep 17 00:00:00 2001 From: katataku Date: Tue, 7 Jan 2025 11:38:46 +0900 Subject: [PATCH] 200. Number of Islands.md --- 200. Number of Islands.md | 159 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 200. Number of Islands.md diff --git a/200. Number of Islands.md b/200. Number of Islands.md new file mode 100644 index 0000000..f7ab24d --- /dev/null +++ b/200. Number of Islands.md @@ -0,0 +1,159 @@ +URL: https://leetcode.com/problems/number-of-islands/description/ + +# Step 1 + +- 実装時間: 10分 +- 高さn、幅mのマップとして、 + - 時間計算量: O(nm) + - 空間計算量: O(nm) + +```python +class Solution: + def numIslands(self, grid: List[List[str]]) -> int: + num_island = 0 + visited = set() + for row in range(len(grid)): + for column in range(len(grid[0])): + if (row, column) in visited or grid[row][column] == '0': + continue + num_island += 1 + islands = [(row, column)] + while islands: + island_row, island_column = islands.pop() + if (island_row, island_column) in visited or grid[island_row][island_column] == '0': + continue + + visited.add((island_row, island_column)) + for dy, dx in [(0, 1), (1, 0), (0, -1), (-1, 0)]: + if 0 <= island_row + dy < len(grid) and 0 <= island_column + dx < len(grid[0]): + islands.append((island_row + dy, island_column + dx)) + + return num_island +``` + +# Step 2 + +- 参考にしたURL + - https://github.com/Hurukawa2121/leetcode/pull/17 + - https://github.com/colorbox/leetcode/pull/31 + - https://github.com/haniwachann/leetcode/pull/3 + - https://github.com/tarinaihitori/leetcode/pull/17 + - https://github.com/hroc135/leetcode/pull/17 + - https://github.com/seal-azarashi/leetcode/pull/17 + - https://github.com/thonda28/leetcode/pull/15 + - https://github.com/goto-untrapped/Arai60/pull/38 + - https://github.com/Ryotaro25/leetcode_first60/pull/18 + - https://github.com/Yoshiki-Iwasa/Arai60/pull/16 + - https://github.com/Mike0121/LeetCode/pull/34 + - https://github.com/tshimosake/arai60/pull/8 + - https://github.com/kazukiii/leetcode/pull/18 + - https://github.com/TORUS0818/leetcode/pull/19 + +- 考えられるアプローチ + - スタックデータ構造 + - https://github.com/Hurukawa2121/leetcode/pull/17/files#r1898905955 + - BFS + - Union Find + - gridの値に-1(visited)や0を書き込んでいく + - 入力である grid に対する破壊的な変更は避けたほうがよい + - https://github.com/hroc135/leetcode/pull/17/files#r1750534861 + +- '0'がマジックナンバーとなっているので、定数化かコメントの付与があると読みやすくなりそうです。 + - https://github.com/Hurukawa2121/leetcode/pull/17/files#r1898871301 + +- `visited`という変数名の代わりに`seen`を使ってる。 + - https://github.com/Hurukawa2121/leetcode/pull/17/files + +- > row, col を使う場合、その最大値として height, width を使うのは違和感があります。 + - この感覚は持てていなかったので学び。 + - https://github.com/colorbox/leetcode/pull/31/files#r1881784335 + +- 範囲チェックを関数化するか悩んだけど、1度しか使わないから不要と思ってやらなかった。 + - より複雑な場合は、「名前をつける」という意味で関数にしてもいいパターンがありそう。 + - https://github.com/colorbox/leetcode/pull/31/files#r1885062583 + +- 命名に悩んでいた`dx, dy` + - > x, y の代わりに delta_row, delta_col としたほうが分かりやすいと感じました。 + - https://github.com/tarinaihitori/leetcode/pull/17#discussion_r1840350347 + +- `len(grid)`も変数に置いておく + - `number_of_rows = len(grid)` + - https://github.com/tarinaihitori/leetcode/pull/17/files#r1840491336 + +- traverseの辞書的な意味を知らなかったので調べた。 + - to cover or extend over an area or time period.(地域や期間をカバーする、または拡張する。) + - https://www.ei-navi.jp/dictionary/content/traverse/?utm_source=chatgpt.com + +- ひとつのセルに対する処理を、関数に分割している人が多かった。 + - 他の方のコードを見た後に、自分のコードを見てみるとネストが深い感じがした。 + - 書いている時には気にならなかったので、他者の目線がたりない。 + +```python +class Solution: + def numIslands(self, grid: List[List[str]]) -> int: + WATER = '0' + LAND = '1' + num_island = 0 + seen = set() + + def traverse(start_row: int, start_column: int) -> None: + islands = [(start_row, start_column)] + while islands: + row, column = islands.pop() + if (row, column) in seen or grid[row][column] == WATER: + continue + seen.add((row, column)) + for delta_row, delta_column in [(0, 1), (1, 0), (0, -1), (-1, 0)]: + next_row = row + delta_row + next_column = column + delta_column + if 0 <= next_row < len(grid) and 0 <= next_column < len(grid[0]): + islands.append((next_row, next_column)) + + for row in range(len(grid)): + for column in range(len(grid[0])): + if (row, column) in seen or grid[row][column] == WATER: + continue + num_island += 1 + traverse(row, column) + return num_island +``` + +# Step 3 + +- 実装時間: 4分 +- 高さn、幅mのマップとして、 + - 時間計算量: O(nm) + - 空間計算量: O(nm) + +```python +class Solution: + def numIslands(self, grid: List[List[str]]) -> int: + num_island = 0 + seen = set() + WATER = '0' + + def traverse(start_row: int, start_col: int) -> None: + islands = [(start_row, start_col)] + while islands: + row, col = islands.pop() + if (row, col) in seen or grid[row][col] == WATER: + continue + seen.add((row, col)) + for delta_row, delta_col in [(0,1), (1,0), (0,-1), (-1,0)]: + next_row = row + delta_row + next_col = col + delta_col + if 0 <= next_row < len(grid) and 0 <= next_col < len(grid[0]): + islands.append((next_row, next_col)) + + for row in range(len(grid)): + for col in range(len(grid[0])): + if (row, col) in seen or grid[row][col] == WATER: + continue + num_island += 1 + traverse(row, col) + return num_island +``` + +- 書いている時に気づいたこと。 + - `column`は`col`とすることで、`row`と文字数が揃う。 + - 省略は基本避けるがcolは共通認識があって許容範囲だと思った。