給定一個二維網格 board 和一個字典中的單詞列表 words,找出全部同時在二維網格和字典中出現的單詞。 單詞必須按照字母順序,經過相鄰的單元格內的字母構成,其中「相鄰」單元格是那些水平相鄰或垂直相鄰的單元格。同一個單元格內的字母在一個單詞中不容許被重複使用。算法
示例:數組
輸入:
words = ["oath","pea","eat","rain"] and board =
[
['o','a','a','n'],
['e','t','a','e'],
['i','h','k','r'],
['i','f','l','v']
]
輸出: ["eat","oath"]
複製代碼
說明: 你能夠假設全部輸入都由小寫字母 a-z 組成。閉包
首先,這道題咱們能夠構建一個Trie樹。 可是,我選擇遞歸。 雖然慢,可是爽。 此次的代碼寫得欠收拾,可是從0到1解決了,從1到多還不是吃豆芽同樣。 走起:app
func findWords(board [][]byte, words []string) []string {
//第一維
lb := len(board)
//第二維,命名請忽略哈哈
lbb := len(board[0])
//依舊閉包上癮
var DFS func (string,int,int,[][]bool) bool DFS = func (s string,x int,y int, flag [][]bool) bool{
if len(s) == 0 {
return true
}
//越界,或者當前字母不知足構成單詞,或者當前字母在當前單詞已被使用過就返回false
if x < 0 || x >= lbb || y < 0 || y >= lb || s[0] != board[y][x] || flag[y][x]{
return false
}
//咱們將當前知足條件的字母記憶化
flag[y][x] = true
//這裏是重點,咱們向四個方向分別遞歸,只要有一個方向能知足就能夠返回true
if DFS (s[1:],x,y+1,flag) || DFS (s[1:],x-1,y,flag) || DFS (s[1:],x,y-1,flag) || DFS (s[1:],x+1,y,flag){
return true
}
//不影響下次
flag[y][x] = false
return false
}
re := []string{}
for _, v := range words {
//這裏我想的是每一個單詞都要從新來一個二維數組判斷字母是否重複。看着很不順眼
flag := [][]bool{}
for i:=0; i<lb; i++ {
flag = append(flag,make([]bool,lbb))
}
//這裏由於不想使用goto,因此來了個二級跳
needBreak := false
for i:=0; i<lb; i++ {
for j:=0; j<lbb; j++ {
if DFS(v,j,i,flag) {
re = append(re,v)
needBreak= true
break
}
}
if needBreak{
break
}
}
}
return re
}
複製代碼
此次的代碼比較不滿意,須要完善的地方太多了,可是我依然以爲思路更重要一些。固然了,對一個極客來講,手寫一個Trie樹,得到最好的性能纔是目標。OK,之後再說咯哈哈。性能
算法夢想家,來跟我一塊兒玩算法,玩音樂,聊聊文學創做,我們一塊兒天馬行空! ui