描述
给定一个二维网格和一个单词,找出该单词是否存在于网格中。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例:
board =
[
['A','B','C','E'],
['S','F','C','S'],
['A','D','E','E']
]
给定 word = "ABCCED", 返回 true.
给定 word = "SEE", 返回 true.
给定 word = "ABCB", 返回 false.
思路
回溯法
注意两点
1. 注意边界 在向四个方向遍历之前 先判断边界 即剪枝
2. 我们在遍历时要将曾经遍历的位置记录下来,往四个方向遍历后要将位置重置 否则下次往其它方向遍历时出错
实现
func exist(board [][]byte, word string) bool {
var ret bool
rows := len(board)
if len(board[0]) == 0 {
return false
}
cols := len(board[0])
for i := 0; i < rows; i++ {
for j := 0; j < cols; j++ {
m := make([][]bool, rows)
for row := 0; row < rows; row++ {
m[row] = make([]bool, cols)
}
ret = existBackTracking(0, board, i, j, word, rows-1, cols-1, m)
if ret == true {
return true
}
}
}
return ret
}
func existBackTracking(index int, board [][]byte, rows, cols int, word string, maxRows, maxCols int, m [][]bool) bool {
if index == len(word)-1 {
return board[rows][cols] == word[index]
}
if board[rows][cols] != word[index] {
return false
}
m[rows][cols] = true
index++
if rows > 0 && m[rows-1][cols] == false {
if existBackTracking(index, board, rows-1, cols, word, maxRows, maxCols, m) {
return true
} else {
m[rows-1][cols] = false
}
}
if rows < maxRows && m[rows+1][cols] == false {
if existBackTracking(index, board, rows+1, cols, word, maxRows, maxCols, m) {
return true
} else {
m[rows+1][cols] = false
}
}
if cols > 0 && m[rows][cols-1] == false {
if existBackTracking(index, board, rows, cols-1, word, maxRows, maxCols, m) {
return true
}else{
m[rows][cols-1] = false
}
}
if cols < maxCols && m[rows][cols+1] == false {
if existBackTracking(index, board, rows, cols+1, word, maxRows, maxCols, m){
return true
}else{
m[rows][cols+1] = false
}
}
return false
}