diff --git a/695. Max Area of Island.md b/695. Max Area of Island.md new file mode 100644 index 0000000..933841d --- /dev/null +++ b/695. Max Area of Island.md @@ -0,0 +1,162 @@ +URL: https://leetcode.com/problems/max-area-of-island/ + +# Step 1 + +- 実装時間: 5分 +- 時間計算量: O(nm) +- 空間計算量: O(nm) + +```python +class Solution: + def maxAreaOfIsland(self, grid: List[List[int]]) -> int: + WATER = 0 + max_area = 0 + seen = set() + + def count_area(start_row: int, start_col: int) -> None: + num_area = 0 + islands = [(start_row, start_col)] + while islands: + row, col = islands.pop() + if (row, col) in seen: + continue + if not (0 <= row < len(grid) and 0 <= col < len(grid[0])): + continue + if grid[row][col] == WATER: + continue + num_area += 1 + seen.add((row, col)) + islands.append((row + 1, col)) + islands.append((row - 1, col)) + islands.append((row, col + 1)) + islands.append((row, col - 1)) + return num_area + + for row in range(len(grid)): + for col in range(len(grid[0])): + max_area = max(max_area, count_area(row, col)) + + return max_area +``` + +昨日の問題と同じ構造を使えるなと思った。 +あえて違う書き方のバリエーションにしてみた。 + +- 呼び出し後のチェックに統一して、チェックを一箇所にしてみた。 +- appendも並べてみた。 +- ifをひとつにまとめると横に長かったので、条件ごとに分割した。 + +# Step 2 + +- 参考にしたURL + - https://github.com/Hurukawa2121/leetcode/pull/18 + - https://github.com/colorbox/leetcode/pull/32 + - https://github.com/tarinaihitori/leetcode/pull/18 + - https://github.com/hroc135/leetcode/pull/18 + - https://github.com/seal-azarashi/leetcode/pull/18 + - https://github.com/Ryotaro25/leetcode_first60/pull/19 + - https://github.com/nittoco/leetcode/pull/24 + - https://github.com/Mike0121/LeetCode/pull/36 + - https://github.com/tshimosake/arai60/pull/9 + - https://github.com/Yoshiki-Iwasa/Arai60/pull/17 + - https://github.com/TORUS0818/leetcode/pull/20 + - https://github.com/kazukiii/leetcode/pull/19 + - https://github.com/goto-untrapped/Arai60/pull/31 + - https://github.com/fhiyo/leetcode/pull/21 + +- > 範囲チェックをして追加という、同じ処理が繰り返されるので関数化をしたりラムダにしたりするのがいいでしょう。 + - https://github.com/colorbox/leetcode/pull/32/files#r1898178545 + - 追加前のチェックにしたほうが効率的なので、書く場合はチェックして追加を関数にまとめる。 + - ifをひとつにすると横長になる件も、関数にすると短くなってひとつのifで見やすくできるかもと思った。 + - > 関数の始めでこれらの条件を確認すると、確かにすっきりはしますが、関数呼び出しのオーバーヘッドはありますね。 + - まさにこの指摘のとおりだ。 + - https://github.com/fhiyo/leetcode/pull/21#discussion_r1638518016 + +- `count_area`という関数名で伝わるとは思うけど、改善の余地がある気もする + - measureIslandArea + - https://github.com/hroc135/leetcode/pull/18/files#r1780052959 + +- https://github.com/kazukiii/leetcode/pull/19#discussion_r1656504693 + - 自分の思いついたのが、常識の範囲内だとわかって嬉しい。 + +- いろんな選択肢が見えていることが大事。 + - 「どこでチェックするのか(append前か後か)」「どのチェックを関数に切り出すのか」あたりが、常識の幅だと思った。 + - UnionFindはみなさんが挑戦しているので、僕もやらねば。。。 + +```python +class Solution: + def maxAreaOfIsland(self, grid: List[List[int]]) -> int: + WATER = 0 + max_area = 0 + seen = set() + + def count_area(start_row: int, start_col: int) -> None: + num_area = 0 + islands = [(start_row, start_col)] + while islands: + row, col = islands.pop() + if (row, col) in seen: + continue + if not (0 <= row < len(grid) and 0 <= col < len(grid[0])): + continue + if grid[row][col] == WATER: + continue + num_area += 1 + seen.add((row, col)) + islands.append((row + 1, col)) + islands.append((row - 1, col)) + islands.append((row, col + 1)) + islands.append((row, col - 1)) + return num_area + + + for row in range(len(grid)): + for col in range(len(grid[0])): + max_area = max(max_area, count_area(row, col)) + + return max_area +``` + +# Step 3 + +- 実装時間: 3分 +- 時間計算量: O(nm) +- 空間計算量: O(nm) + +```python +class Solution: + def maxAreaOfIsland(self, grid: List[List[int]]) -> int: + WATER = 0 + max_area = 0 + seen = set() + + def count_area(start_row: int, start_col: int) -> None: + num_area = 0 + islands = [(start_row, start_col)] + while islands: + row, col = islands.pop() + if (row, col) in seen: + continue + if not (0 <= row < len(grid) and 0 <= col < len(grid[0])): + continue + if grid[row][col] == WATER: + continue + num_area += 1 + seen.add((row, col)) + islands.append((row + 1, col)) + islands.append((row - 1, col)) + islands.append((row, col + 1)) + islands.append((row, col - 1)) + return num_area + + for row in range(len(grid)): + for col in range(len(grid[0])): + max_area = max(max_area, count_area(row, col)) + return max_area +``` + +- 書いた後の感想 + - 昨日までは、「自分の中の最適値として暗記したコードを、出力している」という感覚が若干あった。(そのつもりはなかったけど、今日振り返るとそう感じる) + - 今日は、暗記というより「書くべきことを順次考えつつ、順次書く」という感じに変わった気がした。 + - 「計算機でやりたいことを考える」と「コードを書く作業」の距離が近くなった? + - Step2とStep3の間を半日くらい置いて見たけど、同じコードを書けた。1週間後くらいにやってみる。