2021-09-05:单词搜索 II。给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words,找出所有同时在二维网格和字典中出现的单词。单词必须按照字母顺序,通过 相邻的
2021-09-05:单词搜索 II。给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words,找出所有同时在二维网格和字典中出现的单词。单词必须按照字母顺序,通过 相邻的单元格 内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。力扣212。
福大大 答案2021-09-05:
前缀树。
代码用golang编写。代码如下:
package main
import "fmt"
func main() {
board := [][]byte{{'o', 'a', 'a', 'n'}, {'e', 't', 'a', 'e'}, {'i', 'h', 'k', 'r'}, {'i', 'f', 'l', 'v'}}
words := []string{"oath", "pea", "eat", "rain"}
ret := findWords(board, words)
fmt.Println(ret)
}
type TrieNode struct {
nexts []*TrieNode
pass int
end bool
}
func NewTrieNode() *TrieNode {
ans := &TrieNode{}
ans.nexts = make([]*TrieNode, 26)
ans.pass = 0
ans.end = false
return ans
}
func fillWord(head *TrieNode, word string) {
head.pass++
chs := []byte(word)
index := 0
node := head
for i := 0; i < len(chs); i++ {
index = int(chs[i] - 'a')
if node.nexts[index] == nil {
node.nexts[index] = NewTrieNode()
}
node = node.nexts[index]
node.pass++
}
node.end = true
}
func generatePath(path []byte) string { //LinkedList<Character>
str := make([]byte, len(path))
index := 0
for _, cha := range path {
str[index] = cha
index++
}
return string(str)
}
func findWords(board [][]byte, words []string) []string {
head := NewTrieNode() // 前缀树最顶端的头
set := make(map[string]struct{})
for _, word := range words {
if _, ok := set[word]; !ok {
fillWord(head, word)
set[word] = struct{}{}
}
}
// 答案
ans := make([]string, 0)
// 沿途走过的字符,收集起来,存在path里
path := make([]byte, 0)
for row := 0; row < len(board); row++ {
for col := 0; col < len(board[0]); col++ {
// 枚举在board中的所有位置
// 每一个位置出发的情况下,答案都收集
process(board, row, col, &path, head, &ans)
}
}
return ans
}
// 从board[row][col]位置的字符出发,
// 之前的路径上,走过的字符,记录在path里
// cur还没有登上,有待检查能不能登上去的前缀树的节点
// 如果找到words中的某个str,就记录在 res里
// 返回值,从row,col 出发,一共找到了多少个str
func process(board [][]byte, row int, col int, path *[]byte, cur *TrieNode, res *[]string) int {
cha := board[row][col]
if cha == 0 { // 这个row col位置是之前走过的位置
return 0
}
// (row,col) 不是回头路 cha 有效
index := cha - 'a'
// 如果没路,或者这条路上最终的字符串之前加入过结果里
if cur.nexts[index] == nil || cur.nexts[index].pass == 0 {
return 0
}
// 没有走回头路且能登上去
cur = cur.nexts[index]
*path = append(*path, cha) // 当前位置的字符加到路径里去
fix := 0 // 从row和col位置出发,后续一共搞定了多少答案
// 当我来到row col位置,如果决定不往后走了。是不是已经搞定了某个字符串了
if cur.end {
*res = append(*res, generatePath(*path))
cur.end = false
fix++
}
// 往上、下、左、右,四个方向尝试
board[row][col] = 0
if row > 0 {
fix += process(board, row-1, col, path, cur, res)
}
if row < len(board)-1 {
fix += process(board, row+1, col, path, cur, res)
}
if col > 0 {
fix += process(board, row, col-1, path, cur, res)
}
if col < len(board[0])-1 {
fix += process(board, row, col+1, path, cur, res)
}
board[row][col] = cha
//path.pollLast()
*path = (*path)[0 : len(*path)-1]
cur.pass -= fix
return fix
}
执行结果如下:

2021-09-05:单词搜索 II。给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words,找出所有同时在二维网格和字典中出现的单词。单词必须按照字母顺序,通过 相邻的的更多相关文章
- Leetcode 212.单词搜索II
单词搜索II 给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中"相邻&q ...
- Java实现 LeetCode 212 单词搜索 II(二)
212. 单词搜索 II 给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中&quo ...
- Leetcode之回溯法专题-212. 单词搜索 II(Word Search II)
Leetcode之回溯法专题-212. 单词搜索 II(Word Search II) 给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词. 单 ...
- [LeetCode] 212. 单词搜索 II
题目链接:https://leetcode-cn.com/problems/word-search-ii/ 题目描述: 给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在 ...
- 212. 单词搜索 II
Q: 给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中"相邻" ...
- [Swift]LeetCode212. 单词搜索 II | Word Search II
Given a 2D board and a list of words from the dictionary, find all words in the board. Each word mus ...
- [leetcode] 212. 单词搜索 II(Java)
212. 单词搜索 II 这leetcode的评判机绝对有问题!!同样的代码提交,有时却超时!害得我至少浪费两个小时来寻找更优的答案= =,其实第一次写完的代码就可以过了,靠!!!第207位做出来的 ...
- [LeetCode] Longest Word in Dictionary 字典中的最长单词
Given a list of strings words representing an English Dictionary, find the longest word in words tha ...
- [LeetCode] Longest Word in Dictionary through Deleting 删除后得到的字典中的最长单词
Given a string and a string dictionary, find the longest string in the dictionary that can be formed ...
- 单词搜索 II · Word Search II
[抄题]: 给出一个由小写字母组成的矩阵和一个字典.找出所有同时在字典和矩阵中出现的单词.一个单词可以从矩阵中的任意位置开始,可以向左/右/上/下四个相邻方向移动. 给出矩阵: doafagaidca ...
随机推荐
- database.property文件
注意修改用户名密码 mysql8的版本要注意配置时区 此文件放置连接数据库的相关参数 jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://l ...
- 第一章C语言概述
1.1程序实例 //first.程序 #include <stdio.h> int main() { int num; num = 1; printf("I am a simpl ...
- java多线性--线程创建
java多线性--线程创建 什么是多线程:不同的功能同时进行 Process(进程)与Thread(线程) 进程是执行程序的一次执行过程,是一个动态的概念.是系统分配资源的单位. 一个进程分为多个线程 ...
- Yaml入门与使用
一.入门 1.概念: yml是YAML("YAML Ain't a Markup Language)语言文件,以数据为中心,而不是一标记语言为重点,比json,xml更适合做配置文件. 为 ...
- 剑指offer 第18天
第 18 天 搜索与回溯算法(中等) 剑指 Offer 55 - I. 二叉树的深度 输入一棵二叉树的根节点,求该树的深度.从根节点到叶节点依次经过的节点(含根.叶节点)形成树的一条路径,最长路径的长 ...
- VUE3.x之Proxy 我们为什么要使用Proxy
Object.defineProperty 劫持数据 只是对对象的属性进行劫持 无法监听新增属性和删除属性 需要使用 vue.set, vue.delete 深层对象的劫持需要一次性递归 劫持数组时需 ...
- 几个对js帮助挺多的大佬写的博客
深入理解javascript原型和闭包(完结) JavaScript系列文章 同步异步回调DEMO知乎大佬的this与new解释 宏任务与微任务解析 js闭包 Vue项目中技巧ts学习 ES6基础入门 ...
- cron语句
名称 是否必须 允许值 特殊字符 秒 是 0-59 , - * / 分 是 0-59 , - * / 时 是 0-23 , - * / 日 是 1-31 , - * ? / L W C 月 是 1-1 ...
- ACM-NEFU新生训练2-排序和CMP
A.谁考了第k名-排序 Description 在一次考试中,每个学生的成绩都不相同,现知道了每个学生的学号和成绩,求考第k名学生的学号和成绩. Input 第一行有两个整数,分别是学生的人数n(1≤ ...
- Defi开发简介
Defi开发简介 介绍 Defi是去中心化金融的缩写, 是一项旨在利用区块链技术和智能合约创建更加开放,可访问和透明的金融体系的运动. 这与传统金融形成鲜明对比,传统金融通常由少数大型银行和金融机构控 ...