Skip to content

695.max area of island#18

Open
nicah4o wants to merge 1 commit into
mainfrom
695.max-area-of-island
Open

695.max area of island#18
nicah4o wants to merge 1 commit into
mainfrom
695.max-area-of-island

Conversation

@nicah4o
Copy link
Copy Markdown
Owner

@nicah4o nicah4o commented May 20, 2026

Added detailed explanation and implementation for the max area of island problem using DFS and Union-Find methods.
```

ユニオンファインドは
 1.親をそれぞれの配列の要素が持ち、その親の親の親……と累進した最後の場所の親であるrootをある島の代表として扱う。
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

「累進」という表現に違和感ありますが、あえてこの単語を使った意図はありますか?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

レビューありがとうございます。
こういう表現を見たことがあったので特に意図があってのことではないのですが、遡ると書いた方がいいですね。

};
```

ユニオンファインドは
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Union-Findというデータ構造自体の説明とこの問題固有の話を混同しているようです。別々に記述できますか?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

難しいです。ユニオンファインドに触れたのは今回が初めてなので、これが典型的に用いられる場面が分かっていません。
parent,root,unite,find辺りがデータ構造の話で、縦横に動くというのが固有の話でしょうか。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

AIに聞いたり、Googleで検索したりしましたか?この話に限らずですが…

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

まずは、Union-Findとはどのようなデータ構造であるか、からですかね。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

@liquo-rice @h-masder
ご返信ありがとうございます。お時間を使ってくださっているのに「分からない」で済ませて申し訳ありません。
一応geminiとgoogleは使っています。

union-findはunion(x,y)とfind(x)をメンバー関数として持つアルゴリズムで、木やリストによって実装されます。今回はリストで実装しています。それぞれの要素の所属する集合は素集合(和集合=空集合)であるように配置されます。union(x,y)によりxとyの属する集合を結合します。find(x)によりxの属する集合を判明させます。結合の方法には効率的な方法があります。ある規則で複数の要素を数えるときなどに有効性があります。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

その説明なのですが、素集合系に属する要素(集合)同士の和集合が空集合というのは誤りですね。和集合は、積集合の間違いかと思われます。全体的に言葉の意味を理解して使っているように見えないと読み取れる文章が多々あるように見受けられます。

腑に落ちない場合はとりあえず先に進んでも大丈夫だとは思いますが、分からないことと分かることを区別できるのは大事だと思います。

例えば、メモに「Union-Findの実装は理解したが、用途や数学的な意味はまだピンと来ていない」などと書いておいて、後で振り返って考えてみると良いかもしれません。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

@liquo-rice
ありがとうございます。積集合でした。
そうですね、プログラムの手順と理解度を分けて書いておこうと思います。

Comment on lines +23 to +32
int count = 0;
if (0 <= i && i < grid.size() && 0 <= j && j < grid[0].size() &&
grid[i][j] == 1 && !visited[i][j]) {
visited[i][j] = true;
count = 1 + count_island(visited, grid, i - 1, j) +
count_island(visited, grid, i + 1, j) +
count_island(visited, grid, i, j - 1) +
count_island(visited, grid, i, j + 1);
}
return count;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Early returnで書き直すとどうなりますか?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

    int island(vector<vector<int>>& grid, vector<vector<bool>>& visited, int i,
               int j) {
        int count = 0;
        if (0 > i || i >= grid.size() || 0 > j || j >= grid[0].size())
            return 0;
        if (grid[i][j] == 0 || visited[i][j])
            return 0;
        visited[i][j] = true;
        return island(grid, visited, i - 1, j) +
               island(grid, visited, i + 1, j) +
               island(grid, visited, i, j - 1) +
               island(grid, visited, i, j + 1) + 1;
    }

こうなりますね。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

int count = 0;は不要です。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

if (0 > i || i >= grid.size() || 0 > j || j >= grid[0].size())

この部分が読みにくく感じました。元のコード同様、数直線上に一直線に並ぶよう並べたほうが読みやすいと思います。

if (!(0 <= i && i < grid.size() && 0 <= j && j < grid[0].size())) {

for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[0].size(); j++) {
if (grid[i][j] == 1 && !visited[i][j]) {
int temp = count_island(visited, grid, i, j);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

より適切な変数名は思いつきますか?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

うーん、思いつきません。
temp_countはどうでしょうか。ご意見をお聞かせください。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

area, max_areaとすると良いと思います。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

ありがとうございます。各島の面積<=最大の島の面積なので意味とやっていることが一致しますね。

Comment on lines +37 to +38
int m = grid.size();
int n = grid[0].size();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

変数で置いていますが、下のforループで使うのを忘れているようです。

Comment on lines +67 to +69
for (int i = 0; i < maxsize; i++) {
parent[i] = i;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

iota(parent.begin(), parent.end(), 0)と書けますね。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

ありがとうございます。iotaという便利な関数があるのですね。


200.number of islandsで使用したのと同様のDFSの手段を使用したがデータの破壊を避けるために島を沈没させずにvisitedにて訪問を記録した。
 1.まずcount_island関数を作る。これは配列の(i,j)地点を与えられると、それが島なら一続きの島の面積を返し、海なら0を返す。
 2.これの中身は再帰関数になっており、訪問記録visitedと配列gridを(i,j)と共に引数にする。もし(i,j)地点が島なら、(i,j)をvisitedに追加し、(i,j)の四方一マスについて自分自身を呼び出して探索する。
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

(i,j)をvisitedに追加し

とありますが、visitedはvector<bool>ではないですか?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

そうですね、(i,j)を訪れたのを記録するという意味で書きましたが不正確でした。
visited[i][j]をtrueにする、と書いたほうが良かったです。

200.number of islandsで使用したのと同様のDFSの手段を使用したがデータの破壊を避けるために島を沈没させずにvisitedにて訪問を記録した。
 1.まずcount_island関数を作る。これは配列の(i,j)地点を与えられると、それが島なら一続きの島の面積を返し、海なら0を返す。
 2.これの中身は再帰関数になっており、訪問記録visitedと配列gridを(i,j)と共に引数にする。もし(i,j)地点が島なら、(i,j)をvisitedに追加し、(i,j)の四方一マスについて自分自身を呼び出して探索する。
 3.再帰の一回ごとに現在地点が島ならカウンターに+1をする。島の面積がわかるのであとはgridを走査する。
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

島の面積がわかるのであとはgridを走査する

論理関係がおかしい記述になっていそうでしょうか?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

はい、なっています。

そうすることである島の面積がわかるので、gridを走査すると最大の面積の島がわかる

と書いた方がよいです。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

読んでアルゴリズムがイメージできる説明ではなさそうに見えました。

「gridを走査し、未探索の島ならcount_island()で面積を求め、最大値を探す。」とかでどうでしょう?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

そうですね、プログラムの動作としてはこの記述が正しいです。元の記述は思いつくまでの過程、思考を書きすぎています。

@@ -0,0 +1,124 @@
問題:https://leetcode.com/problems/max-area-of-island/description/
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ちなみにStep 3で3回書き直すのはやっていますか?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

はい、やっています。今回は再帰でやりました。

Comment on lines +23 to +32
int count = 0;
if (0 <= i && i < grid.size() && 0 <= j && j < grid[0].size() &&
grid[i][j] == 1 && !visited[i][j]) {
visited[i][j] = true;
count = 1 + count_island(visited, grid, i - 1, j) +
count_island(visited, grid, i + 1, j) +
count_island(visited, grid, i, j - 1) +
count_island(visited, grid, i, j + 1);
}
return count;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

if (0 > i || i >= grid.size() || 0 > j || j >= grid[0].size())

この部分が読みにくく感じました。元のコード同様、数直線上に一直線に並ぶよう並べたほうが読みやすいと思います。

if (!(0 <= i && i < grid.size() && 0 <= j && j < grid[0].size())) {

```cpp
class Solution {
private:
int count_island(vector<vector<bool>>& visited,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

vector<bool> は特殊化されたコンテナであり、通常の vector<T> とは挙動が一部異なります。要素アクセスにはプロキシオブジェクトが用いられるため、場合によっては動作がやや複雑になったり、オーバーヘッドが発生したりする可能性があります。
また、要素のアドレスを取得できないなど、通常の配列的な扱いができない点にも注意が必要です。
このような特殊性から、vector<bool> の使用を避ける方針のチームもあります。特別な理由がない限りは、vector<char> や vector<uint8_t> などを使うほうが無難だと思います。

class Solution {
private:
int count_island(vector<vector<bool>>& visited,
const vector<vector<int>>& grid, int i, int j) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

こちらのコメントをご参照ください。
mamo3gr/arai60#16 (comment)

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.

4 participants