12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- package main
- // Grid coordinate of single grid
- type Grid struct {
- X int
- Y int
- }
- // UF state of union-find algorithm
- type UF struct {
- ID map[Grid]Grid
- Size map[Grid]int
- Cnt int
- }
- // Union ...
- func (uf *UF) Union(x1, y1, x2, y2 int) {
- g1 := uf.Find(x1, y1)
- g2 := uf.Find(x2, y2)
- if g1 == g2 {
- return
- }
- if uf.Size[g1] < uf.Size[g2] {
- uf.ID[g1] = g2
- uf.Size[g2] += uf.Size[g1]
- } else {
- uf.ID[g2] = g1
- uf.Size[g1] += uf.Size[g2]
- }
- uf.Cnt--
- }
- // Find ...
- func (uf *UF) Find(x, y int) Grid {
- g := Grid{x, y}
- for g != uf.ID[g] {
- g = uf.ID[g]
- }
- return g
- }
- // Connected ...
- func (uf *UF) Connected(x1, y1, x2, y2 int) bool {
- return uf.Find(x1, y1) == uf.Find(x2, y2)
- }
- func numIslands(grid [][]byte) int { // Union-find algorithm
- hei := len(grid)
- if hei == 0 {
- return 0
- }
- wid := len(grid[0])
- var uf UF
- uf.ID = make(map[Grid]Grid)
- uf.Size = make(map[Grid]int)
- for y := 0; y < hei; y++ {
- for x := 0; x < wid; x++ {
- if grid[y][x] == '1' {
- g := Grid{x, y}
- uf.ID[g] = g
- uf.Size[g] = 1
- uf.Cnt++
- }
- }
- }
- for y := 0; y < hei; y++ {
- for x := 0; x < wid; x++ {
- if grid[y][x] == '0' {
- continue
- }
- if x+1 < wid && grid[y][x+1] == '1' {
- uf.Union(x, y, x+1, y)
- }
- if y+1 < hei && grid[y+1][x] == '1' {
- uf.Union(x, y, x, y+1)
- }
- }
- }
- return uf.Cnt
- }
- func main() {
- println(numIslands([][]byte{
- {'1', '1', '0', '0', '0'},
- {'1', '1', '0', '0', '0'},
- {'0', '0', '1', '0', '0'},
- {'0', '0', '0', '1', '1'}}))
- }
|