Skip to content

Max Area of Island.md #17

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 162 additions & 0 deletions 695. Max Area of Island.md
Original file line number Diff line number Diff line change
@@ -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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

宣言から利用まで距離がありますね。
宣言の場所を最後のfor文の直前にすると良いと思います。
変数について覚えておく必要のある距離が減り、記憶力が節約できてコードが読みやすくなります。

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])):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

num_rows = len(grid)
num_cols = len(grid[0])

とおいておくと、 len(grid) と 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()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

二重配列にする選択肢もありますね。


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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

単に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
```

- 書いた後の感想
- 昨日までは、「自分の中の最適値として暗記したコードを、出力している」という感覚が若干あった。(そのつもりはなかったけど、今日振り返るとそう感じる)
- 今日は、暗記というより「書くべきことを順次考えつつ、順次書く」という感じに変わった気がした。
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

コードはいいと思います。

20-30問くらい解いたところで感想記事をネットに公開していただけると助かります。

- 「計算機でやりたいことを考える」と「コードを書く作業」の距離が近くなった?
- Step2とStep3の間を半日くらい置いて見たけど、同じコードを書けた。1週間後くらいにやってみる。