
目录
211. 添加与搜索单词 - 数据结构设计 Design-add-and-search-words-data-structure 🌟🌟
212. 单词搜索 II Word Search ii 🌟🌟🌟
🌟 每日一练刷题专栏 🌟
Rust每日一练 专栏
Golang每日一练 专栏
Python每日一练 专栏
C/C++每日一练 专栏
Java每日一练 专栏
211. 添加与搜索单词 - 数据结构设计 Design-add-and-search-words-data-structure
请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。
实现词典类 WordDictionary :
WordDictionary()初始化词典对象void addWord(word)将word添加到数据结构中,之后可以对它进行匹配bool search(word)如果数据结构中存在字符串与word匹配,则返回true;否则,返回false。word中可能包含一些'.',每个.都可以表示任何一个字母。
示例:
输入:
["WordDictionary","addWord","addWord","addWord","search","search","search","search"]
[[],["bad"],["dad"],["mad"],["pad"],["bad"],[".ad"],["b.."]]
输出:
[null,null,null,null,false,true,true,true]
解释:
WordDictionary wordDictionary = new WordDictionary();
wordDictionary.addWord("bad");
wordDictionary.addWord("dad");
wordDictionary.addWord("mad");
wordDictionary.search("pad"); // 返回 False
wordDictionary.search("bad"); // 返回 True
wordDictionary.search(".ad"); // 返回 True
wordDictionary.search("b.."); // 返回 True
 
提示:
1 <= word.length <= 25addWord中的word由小写英文字母组成search中的word由 '.' 或小写英文字母组成- 最多调用 
10^4次addWord和search 
代码:
package main
import "fmt"
type TrieNode struct {
	children [26]*TrieNode
	isWord   bool
}
type WordDictionary struct {
	root *TrieNode
}
func Constructor() WordDictionary {
	return WordDictionary{root: &TrieNode{}}
}
func (this *WordDictionary) AddWord(word string) {
	node := this.root
	for _, ch := range word {
		idx := ch - 'a'
		if node.children[idx] == nil {
			node.children[idx] = &TrieNode{}
		}
		node = node.children[idx]
	}
	node.isWord = true
}
func (this *WordDictionary) Search(word string) bool {
	return this.match(this.root, word, 0)
}
func (this *WordDictionary) match(node *TrieNode, word string, idx int) bool {
	if node == nil {
		return false
	}
	if idx == len(word) {
		return node.isWord
	}
	ch := word[idx]
	if ch != '.' {
		child := node.children[ch-'a']
		if child != nil && this.match(child, word, idx+1) {
			return true
		}
	} else {
		for _, child := range node.children {
			if child != nil && this.match(child, word, idx+1) {
				return true
			}
		}
	}
	return false
}
func main() {
	wordDictionary := Constructor()
	wordDictionary.AddWord("bad")
	wordDictionary.AddWord("dad")
	wordDictionary.AddWord("mad")
	fmt.Println(wordDictionary.Search("pad"))
	fmt.Println(wordDictionary.Search("bad"))
	fmt.Println(wordDictionary.Search(".ad"))
	fmt.Println(wordDictionary.Search("b.."))
}
 
输出:
false
 true
 true
 true
212. 单词搜索 II Word Search ii
给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words, 返回所有二维网格上的单词 。
单词必须按照字母顺序,通过 相邻的单元格 内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。
示例 1:

输入:board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"] 输出:["eat","oath"]
示例 2:

输入:board = [["a","b"],["c","d"]], words = ["abcb"] 输出:[]
提示:
m == board.lengthn == board[i].length1 <= m, n <= 12board[i][j]是一个小写英文字母1 <= words.length <= 3 * 10^41 <= words[i].length <= 10words[i]由小写英文字母组成words中的所有字符串互不相同
相关题目: 单词搜索 I Word Search i
https://hannyang.blog.csdn.net/article/details/129971403#t0
代码1: 哈希表 + dfs
package main
import "fmt"
type entry struct {
	row, col int
}
func findWords(board [][]byte, words []string) []string {
	n, m := len(board), len(board[0])
	wordIndex := make(map[string]int)
	for i, word := range words {
		wordIndex[word] = i
	}
	visited := make([][]bool, n)
	for i := range visited {
		visited[i] = make([]bool, m)
	}
	dirs := []entry{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}
	var res []string
	var dfs func(string, int, int)
	dfs = func(cur string, i, j int) {
		if idx, ok := wordIndex[cur]; ok {
			res = append(res, words[idx])
			delete(wordIndex, cur)
		}
		for _, dir := range dirs {
			ni, nj := i+dir.row, j+dir.col
			if ni < 0 || ni >= n || nj < 0 || nj >= m || visited[ni][nj] {
				continue
			}
			visited[ni][nj] = true
			dfs(cur+string(board[ni][nj]), ni, nj)
			visited[ni][nj] = false
		}
	}
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			visited[i][j] = true
			dfs(string(board[i][j]), i, j)
			visited[i][j] = false
		}
	}
	return res
}
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"}
	fmt.Println(findWords(board, words))
}
 
代码2: 前缀树 Trie
package main
import "fmt"
type TrieNode struct {
	ch       byte
	children [26]*TrieNode
	word     string
}
type Trie struct {
	root *TrieNode
}
func NewTrie() *Trie {
	return &Trie{root: &TrieNode{}}
}
func (t *Trie) Insert(word string) {
	node := t.root
	for i := 0; i < len(word); i++ {
		ch := word[i]
		if idx := ch - 'a'; idx >= 0 && idx < 26 {
			if node.children[idx] == nil {
				node.children[idx] = &TrieNode{ch: ch}
			}
			node = node.children[idx]
		} else {
			return
		}
	}
	node.word = word
}
func findWords(board [][]byte, words []string) []string {
	trie := NewTrie()
	for _, word := range words {
		trie.Insert(word)
	}
	visited := make([][]bool, len(board))
	for i := 0; i < len(board); i++ {
		visited[i] = make([]bool, len(board[0]))
	}
	var res []string
	var dfs func(node *TrieNode, i, j int)
	dfs = func(node *TrieNode, i, j int) {
		if node.word != "" {
			res = append(res, node.word)
			node.word = "" // 避免重复添加
		}
		if i < 0 || i >= len(board) || j < 0 || j >= len(board[0]) {
			return
		}
		if visited[i][j] || node.children[board[i][j]-'a'] == nil {
			return
		}
		visited[i][j] = true
		idx := board[i][j] - 'a'
		child := node.children[idx]
		dfs(child, i-1, j)
		dfs(child, i+1, j)
		dfs(child, i, j-1)
		dfs(child, i, j+1)
		visited[i][j] = false
	}
	for i := 0; i < len(board); i++ {
		for j := 0; j < len(board[0]); j++ {
			dfs(trie.root, i, j)
		}
	}
	return res
}
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"}
	fmt.Println(findWords(board, words))
}
 
输出:
[oath eat]
🌟 每日一练刷题专栏 🌟
✨ 持续,努力奋斗做强刷题搬运工!
👍 点赞,你的认可是我坚持的动力!
🌟 收藏,你的青睐是我努力的方向!
✎ 评论,你的意见是我进步的财富!
☸ 主页:https://hannyang.blog.csdn.net/
|   
  |  Rust每日一练 专栏(2023.5.16~)更新中...  | 
|   
  |  Golang每日一练 专栏(2023.3.11~)更新中...  | 
|   
  |  Python每日一练 专栏(2023.2.18~2023.5.18)暂停更  | 
|   
  |  C/C++每日一练 专栏(2023.2.18~2023.5.18)暂停更  | 
|   
  |  Java每日一练 专栏(2023.3.11~2023.5.18)暂停更  | 























