-
Notifications
You must be signed in to change notification settings - Fork 0
695. Max Area of Island #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
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,158 @@ | ||
# step1 | ||
思考ログ | ||
- 前回のやつとかなり似ている問題 | ||
- dfsとbfsでどの場面でどう使い分けるのかにピンときていない. | ||
- とりあえず再帰で解こうかな→再帰でやっているけど沼って解けない | ||
- 再帰を使わずに解いた方が簡単な気がしたので方針転換 | ||
- 前回の問題と違って, 0と1がstrではなくintであることに気付かず混乱したが, なんとか解けた. | ||
|
||
```python | ||
class Solution: | ||
def maxAreaOfIsland(self, grid: List[List[int]]) -> int: | ||
WATER = 0 | ||
ISLAND = 1 | ||
visited_island = set() | ||
|
||
num_rows = len(grid) | ||
num_columns = len(grid[0]) | ||
|
||
def inside_island(i, j): | ||
return 0 <= i < num_rows and 0 <= j < num_columns | ||
|
||
def traverse_island(area, row, column): | ||
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. area を引数とせずに、この関数内のローカル変数とする方法もあります。 |
||
island = deque([(row, column)]) | ||
|
||
while island: | ||
r, c = island.popleft() | ||
for (i, j) in ((0, 0), (1, 0), (-1, 0), (0, 1), (0, -1)): | ||
if not inside_island(r + i, c + j): | ||
continue | ||
elif grid[r + i][c + j] == WATER: | ||
continue | ||
elif (r + i, c + j) in visited_island: | ||
continue | ||
|
||
visited_island.add((r + i, c + j)) | ||
island.append((r + i, c + j)) | ||
area += 1 | ||
|
||
return area | ||
|
||
|
||
max_area = 0 | ||
for i in range(num_rows): | ||
for j in range(num_columns): | ||
area = 0 | ||
if grid[i][j] == WATER: | ||
continue | ||
elif (i, j) in visited_island: | ||
continue | ||
area = traverse_island(area, i, j) | ||
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. L45 を見て area = 0 ってなんだろうと思ってここまで読むと、L50 の引数に登場していました。あまり整理できていない段階でコードを書くと不要な部分が含まれることもありますが、書き上げた後、上からコードを読んでシミュレーションすることでコード整理までできれば良さそうと思いました。 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. 解くことに集中してしまって雑になってしまいました、そもそもここで定義する必要がないですね |
||
max_area = max(area, max_area) | ||
|
||
return max_area | ||
``` | ||
|
||
# step2 | ||
- 他の方の解法を参考にする | ||
- https://github.com/potrue/leetcode/pull/17/files?short_path=3c1ad9a#diff-3c1ad9a7fa436a1a165df66488e8abca67c442a6c1b268a312d6be0ea6c169c8 | ||
- ここの[discussion](https://github.com/potrue/leetcode/pull/17/files#r2103404510)は前回の問題でi, jをごちゃごちゃ書いていたのもあり意識するべきだと感じた | ||
- https://github.com/plushn/SWE-Arai60/pull/18#discussion_r2099839166 | ||
|
||
- https://github.com/plushn/SWE-Arai60/pull/18/files?short_path=2e957ae#diff-2e957aed1bb9dc5099abe16f37afb1a7980cfb2170d04ad76a48b4566e75eb35 | ||
- step1で再帰で実装するのを諦めたが際に, この方のstep1をみて実装のミスに気づいた.- [再帰のコールスタック制限を変更するsetrecursionlimit](https://docs.python.org/ja/3/library/sys.html#sys.setrecursionlimit)を見たが, 結局これを設定するのにはどうすれば良いのかわからない. とりあえず知識として持っておこうと思う | ||
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. import sys
sys.setrecursionlimit(1000000) みたいな感じじゃないでしょうか。 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. ありがとうございます、そうですね書き方としてはそちらで良いと思いました。ただ、ここでコメントした"分からない"というのは、値をどの判断基準で設定するのかという点です(説明不足でした)。 例えば概算をしてみて、再帰がどれくらいになりそうだからデフォルトを超えそうなのでXと設定しようみたいにして使うんですかね。 |
||
|
||
- https://github.com/tokuhirat/LeetCode/pull/18/files?short_path=810fef1#diff-810fef11514f386f3a16aee6147492af7b7b23c593173810d148acac46695309 | ||
- https://github.com/shintaro1993/arai60/pull/22/files?short_path=83c7941#diff-83c7941d06b952f77f8ed25bdf52322f3588314fb73e5da782120289b2c4314f | ||
|
||
# step3 | ||
- step1を少し修正 | ||
```python | ||
class Solution: | ||
def maxAreaOfIsland(self, grid: List[List[int]]) -> int: | ||
WATER = 0 | ||
ISLAND = 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. ISLANDではなくLANDのほうがいいかもしれません。ただ結局使われてないので定義しなくてもいいかもです。 |
||
visited_island = set() | ||
|
||
num_rows = len(grid) | ||
num_columns = len(grid[0]) | ||
|
||
def inside_island(row, column): | ||
return 0 <= row < num_rows and 0 <= column < num_columns | ||
|
||
def traverse_and_count_island(row, column): | ||
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. 個人的な感覚かもしれませんが、面積(area)は測ったり計算するものであって数える(count)というイメージではないので、countよりもcalculate_areaなどの名前のほうが適切かもしれません。 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. calculate は数式を用いて計算するというニュアンスを感じます。今回の場合は get_area() あたりが良いと思います。 |
||
island = deque([(row, column)]) | ||
area = 1 | ||
visited_island.add((row, column)) | ||
|
||
while island: | ||
r, c = island.popleft() | ||
for (i, j) in ((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. iとjという名前についてですが、rとi、およびcとjの間に名前の直接的な関連性がないので、少しわかりにくいかもしれないと思いました。 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. r + i, c + j がこんだけ繰り返すならば変数に置きませんか。 あと、append_if_necessary みたいな関数を作って それと、私は i, j は避けるかもしれません。index らしさがあまりないですし、寿命の長い i, j はたまに事故を起こすので。 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. そうですね、ここは改善の余地がありそうです。 コメントいただいたように変数として置き直すとかでも良いと思いました |
||
if not inside_island(r + i, c + j): | ||
continue | ||
elif grid[r + i][c + j] == WATER: | ||
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. 私はこれは if にしますね。elif にする理由がないので。 |
||
continue | ||
elif (r + i, c + j) in visited_island: | ||
continue | ||
area += 1 | ||
island.append((r + i, c + j)) | ||
visited_island.add((r + i, c + j)) | ||
|
||
return area | ||
|
||
max_area = 0 | ||
for i in range(num_rows): | ||
for j in range(num_columns): | ||
if grid[i][j] == WATER: | ||
continue | ||
elif (i, j) in visited_island: | ||
continue | ||
area = traverse_and_count_island(i, j) | ||
max_area = max(area, max_area) | ||
|
||
return max_area | ||
``` | ||
- 再帰でも解いてみた | ||
```python | ||
class Solution: | ||
def maxAreaOfIsland(self, grid: List[List[int]]) -> int: | ||
WATER = 0 | ||
ISLAND = 1 | ||
visited_island = set() | ||
|
||
num_rows = len(grid) | ||
num_columns = len(grid[0]) | ||
|
||
def inside_island(row, column): | ||
return 0 <= row < num_rows and 0 <= column < num_columns | ||
|
||
def traverse_and_count_island(row, column): | ||
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. 好みだと思いますが、シンプルに count_island の方が意図が伝わりやすくなるのかなと思いました。 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. count_island だと、面積ではなく島の数を数えているように感じられました。 |
||
if not inside_island(row, column): | ||
return 0 | ||
elif grid[row][column] == WATER: | ||
return 0 | ||
elif (row, column) in visited_island: | ||
return 0 | ||
|
||
visited_island.add((row, column)) | ||
area = 1 | ||
area += traverse_and_count_island(row + 1, column) | ||
area += traverse_and_count_island(row - 1, column) | ||
area += traverse_and_count_island(row, column + 1) | ||
area += traverse_and_count_island(row, column - 1) | ||
|
||
return area | ||
|
||
|
||
max_area = 0 | ||
for i in range(num_rows): | ||
for j in range(num_columns): | ||
if grid[i][j] == WATER: | ||
continue | ||
elif (i, j) in visited_island: | ||
continue | ||
area = traverse_and_count_island(i, j) | ||
max_area = max(area, max_area) | ||
|
||
return max_area | ||
``` |
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.
あまり明確な基準ではないのですが、自分は以下のように使い分けています。
塗りつぶし等、上記のどれにも当てはまらない場合は、どちらでもよいと思います。その場合は気分で決めることが多いです。