给定一个二维网格 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