LeetCode 题解(92): Word Search II

2024-05-28 09:18
文章标签 leetcode ii 题解 word search 92

本文主要是介绍LeetCode 题解(92): Word Search II,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目:

Given a 2D board and a list of words from the dictionary, find all words in the board.

Each word must be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.

For example,
Given words = ["oath","pea","eat","rain"] and board =

[['o','a','a','n'],['e','t','a','e'],['i','h','k','r'],['i','f','l','v']
]
Return ["eat","oath"].

Note:
You may assume that all inputs are consist of lowercase letters a-z.


题解:

用Word Search I 依次查找words里的每个单词会超时。思路由每次用Word Search I查找word 是否在board里转为, 直接看board上的每个字符,如果该字符存在于由words构建的Trie中,则进行DFS,直到递归到找到某个单词,将该单词加入到result中,同时从Trie中删除该单词。注意Trie需要四个方法:insert, search, searchPre, remove。

C++版:

struct TrieNode {bool leaf;TrieNode* children[26];TrieNode() {leaf = false;for(int i = 0; i < 26; i++) {children[i] = NULL;}}
};class Trie {
public:TrieNode* root;Trie() {root = new TrieNode();}~Trie() {delete root;}void insert(string s) {TrieNode* p = root;for(int i = 0; i < s.length(); i++) {if(p->children[s[i]-'a'] == NULL) {TrieNode* newNode = new TrieNode();p->children[s[i]-'a'] = newNode;}if(i == s.length() - 1)p->children[s[i]-'a']->leaf = true;p = p->children[s[i]-'a'];}}bool search(string s) {if(s.length() == 0)return false;int i = 0;TrieNode* p = root;while(i < s.length()) {if(p->children[s[i]-'a'] == NULL)return false;else {p = p->children[s[i]-'a'];i++;}}if(p->leaf == false)return false;return true;}bool searchPre(string s) {if(s.length() == 0)return false;int i = 0;TrieNode* p = root;while(i < s.length()) {if(p->children[s[i]-'a'] == NULL)return false;else {p = p->children[s[i]-'a'];i++;}}return true;}void remove(string s) {if(s.length() == 0)return;if(search(s) == false)return;int i = 0;TrieNode* p = root;while(i < s.length()) {p = p->children[s[i]-'a'];i++;}p->leaf = false;}
};class Solution {
public:vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {vector<string> results;if(words.size() == 0)return results;Trie tree;for(int i = 0; i < words.size(); i++) {tree.insert(words[i]);}vector<vector<bool>> used(board.size(), vector<bool>(board[0].size(), false));for(int i = 0; i < board.size(); i++) {for(int j = 0; j < board[0].size(); j++) {string s;s.push_back(board[i][j]);if(tree.search(s)) {results.push_back(s);tree.remove(s);}else if(tree.searchPre(s)){used[i][j] = true;exist(board, tree, i+1, j, used, s, results);exist(board, tree, i-1, j, used, s, results);exist(board, tree, i, j+1, used, s, results);exist(board, tree, i, j-1, used, s, results);used[i][j] = false;}s.pop_back();}}return results;}void exist(vector<vector<char>>& board, Trie &tree, int i, int j, vector<vector<bool>> & used, string &s, vector<string>& results) {if(i >= board.size() || i < 0 || j >= board[0].size() || j < 0)return;if(used[i][j] == true)return;s.push_back(board[i][j]);if(tree.search(s)) {results.push_back(s);tree.remove(s);}if(tree.searchPre(s)) {used[i][j] = true;exist(board, tree, i+1, j, used, s, results);exist(board, tree, i-1, j, used, s, results);exist(board, tree, i, j+1, used, s, results);exist(board, tree, i, j-1, used, s, results);used[i][j] = false;}s.pop_back();}
};


Java 版:

class TrieNode {boolean leaf;TrieNode[] children;TrieNode() {leaf = false;children = new TrieNode[26];}
}class Trie {TrieNode root = new TrieNode();void insert(String s) {if(s.length() == 0)return;TrieNode p = root;int i = 0;while(i < s.length()) {if(p.children[s.charAt(i)-'a'] == null) {TrieNode newNode = new TrieNode();p.children[s.charAt(i)-'a'] = newNode;}p = p.children[s.charAt(i)-'a'];i += 1;}p.leaf = true;}void remove(String s) {if(s.length() == 0)return;if(search(s) == false)return;TrieNode p = root;int i = 0;while(i < s.length()) {p = p.children[s.charAt(i)-'a'];i += 1;}p.leaf = false;}boolean search(String s) {if(s.length() == 0)return false;TrieNode p = root;int i = 0;while(i < s.length()) {if(p.children[s.charAt(i)-'a'] == null)return false;else {p = p.children[s.charAt(i)-'a'];i += 1;}}if(p.leaf == false)return false;return true;}boolean searchPre(String s) {if(s.length() == 0)return false;TrieNode p = root;int i = 0;while(i < s.length()) {if(p.children[s.charAt(i)-'a'] == null)return false;else {p = p.children[s.charAt(i)-'a'];i += 1;}}return true;}
}public class Solution {public List<String> findWords(char[][] board, String[] words) {List<String> result = new ArrayList<>();if(board.length == 0 || words.length == 0)return result;boolean[][] used = new boolean[board.length][board[0].length];Trie tree = new Trie();for(String word : words) {tree.insert(word);}for(int i = 0; i < board.length; i++) {for(int j = 0; j < board[0].length; j++) {String s = Character.toString(board[i][j]);if(tree.search(s) == true) {result.add(s);tree.remove(s);}if(tree.searchPre(s) == true) {used[i][j] = true;exist(board, words, used, tree, result, s, i+1, j);exist(board, words, used, tree, result, s, i-1, j);exist(board, words, used, tree, result, s, i, j+1);exist(board, words, used, tree, result, s, i, j-1);used[i][j] = false;}}}return result;}void exist(char[][] board, String[] words, boolean[][] used, Trie tree, List<String> result, String s, int i, int j) {if(i < 0 || i >= board.length || j < 0 || j >= board[0].length)return;if(used[i][j] == true)return;s += Character.toString(board[i][j]);if(tree.search(s) == true) {result.add(s);tree.remove(s);}if(tree.searchPre(s) == true) {used[i][j] = true;exist(board, words, used, tree, result, s, i+1, j);exist(board, words, used, tree, result, s, i-1, j);exist(board, words, used, tree, result, s, i, j+1);exist(board, words, used, tree, result, s, i, j-1);used[i][j] = false;}s = s.substring(0, s.length()-1);}
}

Python版:

Python版超时,但在local machine上test超时case结果是正确的。同时在Trie上加上记录单词个数的size变量,进一步优化,在local machine上 只需2~3ms。但还是超时。

class TrieNode:def __init__(self):self.leaf = Falseself.children = [None] * 26class Trie:def __init__(self):self.root = TrieNode()self.size = 0def insert(self, s):if len(s) == 0:returnp = self.rooti = 0while i < len(s):if p.children[ord(s[i])-ord('a')] is None:new_node = TrieNode()p.children[ord(s[i])-ord('a')] = new_nodep = p.children[ord(s[i])-ord('a')]i += 1p.leaf = Trueself.size += 1def remove(self, s):if len(s) == 0:returnif not self.search(s):returnp = self.rooti = 0while i < len(s):p = p.children[ord(s[i])-ord('a')]i += 1p.leaf = Falseself.size -= 1def search(self, s):if len(s) == 0:return Falsep = self.rooti = 0while i < len(s):if p.children[ord(s[i])-ord('a')] is None:return Falseelse:p = p.children[ord(s[i])-ord('a')]i += 1if not p.leaf:return Falsereturn Truedef searchPre(self, s):if len(s) == 0:return Falsep = self.rooti = 0while i < len(s):if p.children[ord(s[i])-ord('a')] is None:return Falseelse:p = p.children[ord(s[i])-ord('a')]i += 1return Trueclass Solution:# @param {character[][]} board# @param {string[]} words# @return {string[]}def findWords(self, board, words):result = []if len(board) == 0 or len(words) == 0:return resultused = [[False] * len(board[0]) for i in range(len(board)) ]tree = Trie()for word in words:tree.insert(word)for i in range(len(board)):for j in range(len(board[0])):if tree.size == 0:return results = board[i][j]if tree.search(s):result.append(s)tree.remove(s)if tree.searchPre(s):used[i][j] = Trueself.exist(board, words, used, tree, result, s, i+1, j)self.exist(board, words, used, tree, result, s, i-1, j)self.exist(board, words, used, tree, result, s, i, j+1)self.exist(board, words, used, tree, result, s, i, j-1)used[i][j] = Falsereturn resultdef exist(self, board, words, used, tree, result, s, i, j):if tree.size == 0:returnif i < 0 or i >= len(board) or j < 0 or j >= len(board[0]):returnif used[i][j]:returns += board[i][j]if tree.search(s):result.append(s)tree.remove(s)if tree.searchPre(s):used[i][j] = Trueself.exist(board, words, used, tree, result, s, i+1, j)self.exist(board, words, used, tree, result, s, i-1, j)self.exist(board, words, used, tree, result, s, i, j+1)self.exist(board, words, used, tree, result, s, i, j-1)used[i][j] = Falses = s[0:len(s)-1]




这篇关于LeetCode 题解(92): Word Search II的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1010148

相关文章

HTML5 搜索框Search Box详解

《HTML5搜索框SearchBox详解》HTML5的搜索框是一个强大的工具,能够有效提升用户体验,通过结合自动补全功能和适当的样式,可以创建出既美观又实用的搜索界面,这篇文章给大家介绍HTML5... html5 搜索框(Search Box)详解搜索框是一个用于输入查询内容的控件,通常用于网站或应用程

C#实现将Office文档(Word/Excel/PDF/PPT)转为Markdown格式

《C#实现将Office文档(Word/Excel/PDF/PPT)转为Markdown格式》Markdown凭借简洁的语法、优良的可读性,以及对版本控制系统的高度兼容性,逐渐成为最受欢迎的文档格式... 目录为什么要将文档转换为 Markdown 格式使用工具将 Word 文档转换为 Markdown(.

Python实现自动化Word文档样式复制与内容生成

《Python实现自动化Word文档样式复制与内容生成》在办公自动化领域,高效处理Word文档的样式和内容复制是一个常见需求,本文将展示如何利用Python的python-docx库实现... 目录一、为什么需要自动化 Word 文档处理二、核心功能实现:样式与表格的深度复制1. 表格复制(含样式与内容)2

Python实现一键PDF转Word(附完整代码及详细步骤)

《Python实现一键PDF转Word(附完整代码及详细步骤)》pdf2docx是一个基于Python的第三方库,专门用于将PDF文件转换为可编辑的Word文档,下面我们就来看看如何通过pdf2doc... 目录引言:为什么需要PDF转Word一、pdf2docx介绍1. pdf2docx 是什么2. by

如何Python使用设置word的页边距

《如何Python使用设置word的页边距》在编写或处理Word文档的过程中,页边距是一个不可忽视的排版要素,本文将介绍如何使用Python设置Word文档中各个节的页边距,需要的可以参考下... 目录操作步骤代码示例页边距单位说明应用场景与高级用China编程途小结在编写或处理Word文档的过程中,页边距是一个

Python使用python-docx实现自动化处理Word文档

《Python使用python-docx实现自动化处理Word文档》这篇文章主要为大家展示了Python如何通过代码实现段落样式复制,HTML表格转Word表格以及动态生成可定制化模板的功能,感兴趣的... 目录一、引言二、核心功能模块解析1. 段落样式与图片复制2. html表格转Word表格3. 模板生

Java如何根据word模板导出数据

《Java如何根据word模板导出数据》这篇文章主要为大家详细介绍了Java如何实现根据word模板导出数据,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... pom.XML文件导入依赖 <dependency> <groupId>cn.afterturn</groupId>

Python实现word文档内容智能提取以及合成

《Python实现word文档内容智能提取以及合成》这篇文章主要为大家详细介绍了如何使用Python实现从10个左右的docx文档中抽取内容,再调整语言风格后生成新的文档,感兴趣的小伙伴可以了解一下... 目录核心思路技术路径实现步骤阶段一:准备工作阶段二:内容提取 (python 脚本)阶段三:语言风格调

Java利用docx4j+Freemarker生成word文档

《Java利用docx4j+Freemarker生成word文档》这篇文章主要为大家详细介绍了Java如何利用docx4j+Freemarker生成word文档,文中的示例代码讲解详细,感兴趣的小伙伴... 目录技术方案maven依赖创建模板文件实现代码技术方案Java 1.8 + docx4j + Fr

vue使用docxtemplater导出word

《vue使用docxtemplater导出word》docxtemplater是一种邮件合并工具,以编程方式使用并处理条件、循环,并且可以扩展以插入任何内容,下面我们来看看如何使用docxtempl... 目录docxtemplatervue使用docxtemplater导出word安装常用语法 封装导出方