934.最短的桥

75 阅读1分钟

题目:

算法:
方法一:模拟
错误解法,岛可能占多个格子

func shortestBridge(grid [][]int) int {
	islands := make([][]int, 0)
	for i := range grid {
		for j := range grid[i] {
			if grid[i][j] == 1 {
				islands = append(islands, []int{i, j})
				if len(islands) == 2{
					break
				}
			}
		}
		if len(islands) == 2{
			break
		}
	}
	diffX := absDiff(islands[0][0], islands[1][0])
	diffY := absDiff(islands[0][1], islands[1][1]) 
	if diffX == 0 {
		return diffY - 1
	}
	if diffY == 0 {
		return diffX - 1
	}
	return diffX  + diffY - 1
}

func absDiff(a, b int) int {
	if a > b {
		return a - b
	}
	return b - a
}

方法二: bfs
总体思路为:
1.先找到第一个岛的所有格子放island队列中,将这些格子设置为-1,避免重复遍历,
2.然后从island的每个格子上下左右走一步,并将新遍历到的格子放到island队列中,原有的格子都遍历完成一次时step ++,如果找到了新岛则返回步数step

func shortestBridge(grid [][]int) int {
	pairs := [][]int{[]int{-1, 0},[]int{1, 0},[]int{0, 1},[]int{0, -1}}
	islands := make([][]int, 0)
	n := len(grid)
	found := false
	for i := range grid {
		for j := range grid[i] {
			if grid[i][j] == 1 {
				islands = append(islands, []int{i, j})
				grid[i][j] = -1
				found = true
				break
			}	
		}
		if found {
			break
		}
	}

	index := 0
	// fmt.Println(islands)
	for index < len(islands){
		island := islands[index]
		for i := range pairs {
			x := island[0] + pairs[i][0]
			y := island[1] + pairs[i][1]
			if 0 <= x && x < n && 0 <= y && y < n && grid[x][y] == 1 {
				grid[x][y] = -1
				islands = append(islands, []int{x, y})
			}
		}
		index ++
	}
	// fmt.Println("grid", grid)
	// 第一个岛的所有格子已经在islands中
	step := 0
	for len(islands) != 0 {
		queue := make([][]int, 0)
		for i := range islands {
			island := islands[i]
			for i := range pairs {
				x := island[0] + pairs[i][0]
				y := island[1] + pairs[i][1]
				if 0 <= x && x < n && 0 <= y && y < n {
					if grid[x][y] == 1 {
						return step
					} else if grid[x][y] == 0 {
						// 遍历过了标记
						grid[x][y] = -1
						queue = append(queue, []int{x, y})
					}
				}
			}
		}
		islands = queue
		queue = nil
		step ++
		// fmt.Println("islands", step, islands)
	}
	return -1
}