695. Max Area of Island#18
Conversation
ece085a to
a71369f
Compare
| } | ||
|
|
||
| func sink(grid [][]int, i, j int) int { | ||
| if i < 0 || i >= len(grid) || j < 0 || j >= len(grid[0]) || grid[i][j] != 1 { |
There was a problem hiding this comment.
条件式を適宜分割すると見やすいと思うのですが、いかがでしょうか
if i < 0 || i >= len(grid) {
return 0
}
if j < 0 || j >= len(grid[0]) {
return 0
}
if grid[i][j] != 1 {
return 0
}There was a problem hiding this comment.
そう思います.3回目はそのように書いてみました.
There was a problem hiding this comment.
数直線上に一直線上に並ぶように並べると、より見やすくなると思います。
if !(0 <= i && i < len(grid)) {
return 0
}
if !(0 <= j && j < len(grid[0])) {
return 0
}There was a problem hiding this comment.
自分は否定条件をつかうとすこしだけ読解の負荷があがる感じがして,一律で避けがちでしたが,
この場合だと,配列のレンジチェックということがわかり,そこまで負荷ではないですね.アリだなと感じました.
コメントありがとうございます
| for i := range grid { | ||
| for j := range grid[i] { | ||
| if grid[i][j] == 1 { | ||
| maxArea = max(maxArea, sink(grid, i, j)) |
There was a problem hiding this comment.
sinkのかわりに島の大きさを測る関数名がよいと思いました。
measureIslandSizeなどはいかがでしょうか?
There was a problem hiding this comment.
これはたしかに.自分では見逃してました.
自分の感覚だと,面積を測定するというように捉えていたので,measureIslandArea としたいと思いました.
| ``` | ||
| - 最初のマスを塗りつぶしするのが抜けていた. | ||
| - out-of-placeと,DFSをloopにするのはできた. | ||
| - BFSはまだ実装がスッとでてくる状態じゃなかったので,次回以降にまた取り組むことにした |
There was a problem hiding this comment.
DFS loopが書けているので、そこからBFSを理解するとよさそうです。
深さ優先探索では Last In First Out (LIFO) によって探索を進めます。
一方、幅優先探索では First In First Out (FIFO) にすることで、近い位置から順に探索していきます。
func sink(grid [][]int, i, j int) int {
area := 0
grid[i][j] = 0
queue := [][2]int{{i, j}}
for len(queue) > 0 {
area += 1
cell := queue[0]
queue = queue[1:]
for _, d := range [4][2]int{{1, 0}, {-1, 0}, {0, 1}, {0, -1}} {
ni, nj := cell[0]+d[0], cell[1]+d[1]
if ni < 0 || ni >= len(grid) || nj < 0 || nj >= len(grid[0]) || grid[ni][nj] != 1 {
continue
}
grid[ni][nj] = 0
queue = append(queue, [2]int{ni, nj})
}
}
return area
}There was a problem hiding this comment.
話はそれますが、stack, queueなどの変数名は、役割にしたほうが見やすいかと思います。
func sink(grid [][]int, row, column int) int {
area := 0
grid[row][column] = 0
frontier := [][2]int{{row, column}}
for len(frontier) > 0 {
position := frontier[0] // cell := stack[len(stack)-1] を変更
frontier = frontier[1:] // stack = stack[:len(stack)-1]
area++
for _, direction := range [4][2]int{{1, 0}, {-1, 0}, {0, 1}, {0, -1}} {
neighborRow := position[0] + direction[0]
neighborColumn := position[1] + direction[1]
if neighborRow < 0 || neighborRow >= len(grid) {
continue
}
if neighborColumn < 0 || neighborColumn >= len(grid[0]) {
continue
}
if grid[neighborRow][neighborColumn] != 1 {
continue
}
grid[neighborRow][neighborColumn] = 0
frontier = append(frontier, [2]int{neighborRow, neighborColumn})
}
}
return area
}There was a problem hiding this comment.
話を元に戻して、
最初の幅優先探索は、深さごとに管理されておらず好みではないので、私は以下のように書いたりします。
func sink(grid [][]int, i, j int) int {
area := 0
grid[i][j] = 0
frontier := [][2]int{{i, j}}
for len(frontier) > 0 {
nextFrontier := [][2]int{}
for _, position := range frontier {
area++
for _, direction := range [4][2]int{{1, 0}, {-1, 0}, {0, 1}, {0, -1}} {
neighborRow := position[0] + direction[0]
neighborColumn := position[1] + direction[1]
if neighborRow < 0 || neighborRow >= len(grid) {
continue
}
if neighborColumn < 0 || neighborColumn >= len(grid[0]) {
continue
}
if grid[neighborRow][neighborColumn] != 1 {
continue
}
grid[neighborRow][neighborColumn] = 0
nextFrontier = append(nextFrontier, [2]int{neighborRow, neighborColumn})
}
}
frontier = nextFrontier
}
return area
}There was a problem hiding this comment.
ありがとうございます!
frontier, directionという命名,とてもよいですね.
dはdeltaくらいのつもりでしたが,directionのほうが役割と一致していてよさそうです.
一点area++の位置だけ,もうひとつ外側のループに配置すべきかなとは思いました.
それはともかく,コメントありがとうございます
https://leetcode.com/problems/max-area-of-island