1. 程式人生 > 實用技巧 >leetcode之79單詞搜尋Golang

leetcode之79單詞搜尋Golang

題目描述

給定一個二維網格和一個單詞,找出該單詞是否存在於網格中。

單詞必須按照字母順序,通過相鄰的單元格內的字母構成,其中“相鄰”單元格是那些水平相鄰或垂直相鄰的單元格。同一個單元格內的字母不允許被重複使用。

示例:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

給定 word = "ABCCED", 返回 true
給定 word = "SEE", 返回 true
給定 word = "ABCB", 返回 false

演算法

本題採用回溯法解決,深度遍歷到最深處如果是正確結果,就直接返回,如果在這之間,遇到了錯誤,那麼就直接往回退

本題演算法

  • 定義一個二維陣列[][]bool,他的初始值為false,他的元素數量和board的元素數量一樣多,某些位置的值為true的時候,說明這個字元已經被用來匹配了,不能繼續用來匹配
  • 首先遍歷二維byte陣列,找到與單詞第一個字元匹配的地方,然後進入遞迴函式進行深度遍歷
    • 首先判斷這是不是已經判斷完單詞的最後一個字元,如果是就直接返回true
    • 判斷在board中,該字元的上下左右是否存在字元,並且存在的字元是否已經被用來匹配並且這個字元是否匹配單詞的下一個字元
      • 如果能夠匹配就修改[][]byte的值,並且繼續向深處匹配,直到單詞的最後一位或者出現了錯誤,上下左右都走不通
      • 如果不能匹配就換個方向,當上下左右都不能匹配,那麼就返回錯誤
  • 返回遞迴函式的結果,如果結果是true,就直接返回,如果結果是false,那麼就重新找一個匹配單詞開始字元的地方繼續深度匹配
  • 當找完board都沒有匹配成功,就返回false

程式碼

func exist(board [][]byte, word string) bool {
	if len(word) == 0 {
		return true
	}
	if len(board) == 0 || len(board[0]) == 0 {
		return false
	}
	boolBoard := make([][]bool, len(board))
	for i := 0; i < len(boolBoard); i++ {
		boolBoard[i] = make([]bool, len(board[0]))
	}
	var recursion func(row, column, index int) bool
	recursion = func(row, column, index int) bool {
		if index == len(word) {
			return true
		}
		// 分別找上下左右的點,並且這個點滿足兩個條件
		// 1是這個點的boardBool為false,2是這個點的board的值與單詞中的字元相同
		top, down, left, right := false, false, false, false
		if row-1 >= 0 && !boolBoard[row-1][column] && board[row-1][column] == byte(word[index]) {
			boolBoard[row-1][column] = true
			top = recursion(row-1, column, index+1)
			boolBoard[row-1][column] = false
		}
		if top {
			return true
		}
		if row+1 < len(board) && !boolBoard[row+1][column] && board[row+1][column] == byte(word[index]) {
			boolBoard[row+1][column] = true
			down = recursion(row+1, column, index+1)
			boolBoard[row+1][column] = false
		}
		if down {
			return true
		}
		if column-1 >= 0 && !boolBoard[row][column-1] && board[row][column-1] == byte(word[index]) {
			boolBoard[row][column-1] = true
			left = recursion(row, column-1, index+1)
			boolBoard[row][column-1] = false
		}
		if left {
			return true
		}
		if column+1 < len(board[0]) && !boolBoard[row][column+1] && board[row][column+1] == byte(word[index]) {
			boolBoard[row][column+1] = true
			right = recursion(row, column+1, index+1)
			boolBoard[row][column+1] = false
		}
		if right {
			return true
		}
		return false
	}
	res := false
	for i := 0; i < len(board); i++ {
		for j := 0; j < len(board[0]); j++ {
			if board[i][j] == byte(word[0]) {
				boolBoard[i][j] = true
				res = recursion(i, j, 1)
				boolBoard[i][j] = false
				if res {
					return res
				}
			}
		}
	}
	return false
}