Skip to content

695. Max Area of Island#18

Open
n6o wants to merge 1 commit intomainfrom
max-area-of-island
Open

695. Max Area of Island#18
n6o wants to merge 1 commit intomainfrom
max-area-of-island

Conversation

@n6o
Copy link
Owner

@n6o n6o commented Feb 16, 2026

今回の問題

Max Area of Island - LeetCode

使用言語

Go

次に解く問題

Maximum Depth of Binary Tree - LeetCode

}

// 行が範囲外
if adjacent.row < 0 || rowSize <= adjacent.row {

Choose a reason for hiding this comment

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

数直線をイメージしてその外側にあるからこの書き方なのでしょうか?
逆に!(0 <= row && row < rowSize)と書く方もいましたので紹介します。

Copy link
Owner Author

Choose a reason for hiding this comment

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

ありがとうございます。そのイメージです。

func exploreIsland(startCell Cell, grid [][]int) int {
rowSize := len(grid)
columnSize := len(grid[0])
isValidLand := func(row, column int) bool {
Copy link

@PafsCocotte PafsCocotte Feb 16, 2026

Choose a reason for hiding this comment

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

ループの中で毎回これを生成するならば、外で関数定義したほうがいいと思います。

Copy link
Owner Author

Choose a reason for hiding this comment

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

そうですね、外に出すなら構造体のメソッドとして定義します。

var maxArea int
for row := range grid {
for column := range grid[row] {
if grid[row][column] != LAND {

Choose a reason for hiding this comment

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

下にあるisValidLandを使う、あるいは不要な分岐を省きたければisValidとisLandにわかれていれば、ここも関数で同じように書けるように見えます。

Copy link

@PafsCocotte PafsCocotte Feb 16, 2026

Choose a reason for hiding this comment

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

なお、今回のdfsの書き方は、陸であることを確認してから探検するという書き方ですが、海や境界外だったらすぐ帰るという書き方をすれば、関数最初にearly returnするだけで、exploreIslandを呼び出す際には海も境界も気にする必要がなくなるので、もう少し楽に書けると思います。

Copy link
Owner Author

Choose a reason for hiding this comment

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

そうですね、記述量は減ると思います。
私が読むとしたら、陸でないのに探索するのはなぜだろうと思ってしまうので、こんなふうに書いてしまいます。

nextLands := []Cell{startCell}
for len(nextLands) > 0 {
land := nextLands[len(nextLands) - 1]
nextLands = nextLands[:len(nextLands) - 1]

Choose a reason for hiding this comment

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

ここに
grid[startCell.row][startCell.column] = WATER
を書けば、1個目の陸だけ特別扱いでこのfor文の前に沈めるとかせずに済んだように見えています。

Copy link
Owner Author

Choose a reason for hiding this comment

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

同じセルを2回以上スタックに積まないようにするために、入れる前に更新しています。
スタックから取り出した後に更新する場合、再度同じセルがスタックに積まれる可能性があると考えています。


スタックから取り出した後に更新する場合でも正しく大きさを計算できるか考えてみます。

column int
}

func exploreIsland(startCell Cell, grid [][]int) int {

Choose a reason for hiding this comment

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

私の理解が足りていなかったのですが、この関数は引数のstartCellが陸かつvalidでないといけないんですよね。
せっかく再利用もできるのですから、関数の責務をどこまで持つかという話ですが、陸を要求するならばassertや例外スローなどでそれを明示しておいた方が関数のユーザーにとって使いやすいです。

queue := []Cell{startCell}
for len(queue) > 0 {
cell := queue[0]
queue = queue[1:]
Copy link

Choose a reason for hiding this comment

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

スライスを上書きしても、背後のデータはそのままなんですね(コピーされない)。Pythonだとコピーされてしまうので羨ましいです。

https://go.dev/blog/slices-intro

Slicing does not copy the slice’s data. It creates a new slice value that points to the original array.

### 1. 幅優先探索で島を探索し、面積の最大値を求める

- 以前やった島を数えるのとだいたい同じ
- grid をコピーする
Copy link

Choose a reason for hiding this comment

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

訪問済みの島を管理するデータ構造について、選択肢の幅を検討できるとなお良いと思いました(前問で検討済みでしたらご放念ください)。

  • row, col -> bool のMap
  • [][]bool のスライス(grid と同じサイズ)

個人的には、処理中に WATER で塗りつぶしてしまうと、もとが島だったのかどうかの履歴が失われてしまい、デバッグにやや不便だったり、仕様変更や機能追加の際に手間がかかりそうに思いました。

Copy link
Owner Author

Choose a reason for hiding this comment

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

ありがとうございます。

別管理にする場合、状態を管理する構造体を定義し、そのメソッド内で参照する形にすると思います。
islandExplorer みたいな感じです

関数の引数として渡す形式にする場合、参照用の grid と管理用の何かを渡すので、それを嫌いました。

column: land.column + offset.column,
}

if !isValidLand(adjacent.row, adjacent.column) {
Copy link

Choose a reason for hiding this comment

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

valid は人によって想像する条件が異なりうるので、さらに具体的な命名にするとなお良いと思いました(今回の短さなら関数を読めばいいのですが、それすらスキップできる可能性もあります)。

  • grid内である
  • LAND である
  • 訪問済みである

Copy link
Owner Author

Choose a reason for hiding this comment

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

ありがとうございます。

LANDをWATERに変える方針にしたので、フィットする関数名に悩みました。
いまだに思いついてはいないので、改善するとしたら下記から選ぶと思います。

  • 関数ではなくそのまま記載する
  • コメントでフォローする

@mamo3gr
Copy link

mamo3gr commented Feb 18, 2026

全体的に読みやすかったです!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants