LeetCode刷题:212. 单词搜索 II (golang版)
-
题目描述
-
思路 1、跟单词搜索 I不同的是处理的数据多了,所以不能再用之前的方法简单的为每个单词进行深度搜索然后汇总,会超时 2、用前缀树tria,先将单词构建成一颗trial树,然后进行处理 代码
package main
import (
"fmt"
)
//前缀树结构,注意childres是map,这样才能用O(1)时间查找到孩子节点
type Tria struct{
childres map[string]*Tria
isWord bool
}
func findWords(board [][]byte, words []string) []string {
//先构建tria树
var root = new(Tria)
rootb := root
//遍历单词切片
for _,v := range words {
//根节点地址另存一份,每个单词在构建tria时都要用
root = rootb
//单词字符串,将每个字符串字符填入前缀树中
for _,v2 := range v {
if root.childres[string(v2)] == nil {
tmp := new(Tria)
if root.childres == nil {
root.childres = make(map[string]*Tria)
}
root.childres[string(v2)] = tmp
}
root = root.childres[string(v2)]
}
//标记到此为止是个单词
root.isWord = true
}
//开始处理
var (
//log保存状态位,true代表已被使用过
log [12][12]bool
str string
//因为单词可能有重复的,所有先存在map中去重,再将map转为切片返回
res = make([]string,0)
resM = make(map[string]bool)
)
//遍历board,每个符合第一个单词前缀的格子都进行递归处理
for i:=0; i<len(board); i++ {
for j:=0; j<len(board[0]); j++ {
if rootb.childres[string(board[i][j])] != nil {
DFS(&board,rootb,log,i,j,str,&resM)
}
}
}
//转为题目要求的切片类型
for k,v := range resM {
if v == true {
res = append(res,k)
}
}
return res
}
//深度优先遍历,log是标志位,true代表已被使用过,rowI和colI是行列下标,str是前缀字符串,resM保存符合要求的单词
func DFS(board *[][]byte, root *Tria, log [12][12]bool, rowI int,colI int,str string,resM *map[string]bool) {
var (
row = len(*board)
col = len((*board)[0])
)
//递归终止条件,下标越界或已被使用过,不符合要求,终止递归
if colI >= col || colI < 0 || rowI >= row || rowI < 0 || log[rowI][colI] == true {
return
}
//当前节点不存在该字符,不符合要求,终止递归
if root.childres[string((*board)[rowI][colI])] == nil {
return
}
//符合要求,将前缀树字符转为字符串Word
str += string((*board)[rowI][colI])
//通过标志位isWord判断是否为单词,若是则保存到resM中
if root.childres[string((*board)[rowI][colI])].isWord == true {
(*resM)[str] = true
}
//将该位置标为已被使用过
log[rowI][colI] = true
//依次处理当前位置的上下左右位置
DFS(board,root.childres[string((*board)[rowI][colI])],log,rowI+1,colI,str,resM)
DFS(board,root.childres[string((*board)[rowI][colI])],log,rowI-1,colI,str,resM)
DFS(board,root.childres[string((*board)[rowI][colI])],log,rowI,colI+1,str,resM)
DFS(board,root.childres[string((*board)[rowI][colI])],log,rowI,colI-1,str,resM)
}
func main() {
var tmp = []byte{
o,a,b,n}
var t [][]byte
t = append(t,tmp)
tmp = []byte{
o,t,a,e}
t = append(t,tmp)
tmp = []byte{
a,h,k,r}
t = append(t,tmp)
tmp = []byte{
a,f,l,v}
t = append(t,tmp)
words := []string{
"oa","oaa","ot","ah"}
res := findWords(t,words)
fmt.Println(res)
}
上一篇:
IDEA上Java项目控制台中文乱码
