class Solution {
public:
vector<string> findAllConcatenatedWordsInADict(vector<string>& words) {
}
};
472. 连接词
给你一个 不含重复 单词的字符串数组 words
,请你找出并返回 words
中的所有 连接词 。
连接词 定义为:一个完全由给定数组中的至少两个较短单词组成的字符串。
示例 1:
输入:words = ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"] 输出:["catsdogcats","dogcatsdog","ratcatdogcat"] 解释:"catsdogcats" 由 "cats", "dog" 和 "cats" 组成; "dogcatsdog" 由 "dog", "cats" 和 "dog" 组成; "ratcatdogcat" 由 "rat", "cat", "dog" 和 "cat" 组成。
示例 2:
输入:words = ["cat","dog","catdog"] 输出:["catdog"]
提示:
1 <= words.length <= 104
0 <= words[i].length <= 30
words[i]
仅由小写字母组成0 <= sum(words[i].length) <= 105
相似题目
原站题解
php 解法, 执行用时: 288 ms, 内存消耗: 37.9 MB, 提交时间: 2023-10-09 10:39:02
class Solution { /** * @param String[] $words * @return String[] */ function findAllConcatenatedWordsInADict($words) { $this->root = new TrieNode(); uasort($words, [$this, 'sortByLength']); $ret = []; foreach ($words as $word) { if(strlen($word)==0){ continue; }elseif ($this->helper($word)) { array_push($ret, $word); }else{ $this->addWord($word); } } return $ret; } function sortByLength($a,$b) { return strlen($a) - strlen($b); } function helper($word) { if(strlen($word)==0) return true; $tree = $this->root; for ($i=0; $i < strlen($word); $i++) { $c = $word[$i]; $tree = $tree->next[$c]; if(!$tree){ return false; } if($tree->isWord){ if($this->helper(substr($word, $i+1))){ return true; } } } return false; } function addWord($word) { $tree = $this->root; for ($i=0; $i < strlen($word); $i++) { $c = $word[$i]; if(!isset($tree->next[$c])){ $tree->next[$c] = new TrieNode(); } $tree = $tree->next[$c]; } if(!$tree->isWord){ $tree->isWord = true; } } } // 字典树 class TrieNode { public $isWord = false; public $next = []; }
python3 解法, 执行用时: 348 ms, 内存消耗: 27.4 MB, 提交时间: 2023-10-09 10:37:28
class Solution: def findAllConcatenatedWordsInADict(self, words: List[str]) -> List[str]: def helper(word: str, root: dict) -> bool: if len(word) == 0: return True tree = root for i,c in enumerate(word): tree = tree.get(c, None) if not tree: return False if '#' in tree: if helper(word[i+1:], root): return True return False def addWord(word: str) -> None: tree = root for c in word: if c not in tree: tree[c] = {} tree = tree[c] tree['#'] = {} words.sort(key=lambda x: len(x)) ret = [] root = {} for word in words: if len(word)==0: continue if helper(word, root): ret.append(word) else: addWord(word) return ret
javascript 解法, 执行用时: 256 ms, 内存消耗: 73.4 MB, 提交时间: 2023-10-09 10:35:00
/** * @param {string[]} words * @return {string[]} */ var findAllConcatenatedWordsInADict = function(words) { const root = new Trie(), ans = []; words.sort((a,b)=>(a.length - b.length)); for(const word of words){ if(word.length == 0) continue; if(root.find(root, word)) ans.push(word); else root.insert(word); } return ans; }; class Trie{ constructor(){ this.children = new Array(26); this.isEnd = false; } insert(word){ let node = this; for(let i=0;i<word.length;i++){ const idx = word.charCodeAt(i) - 'a'.charCodeAt(0); if(node.children[idx] === undefined) node.children[idx] = new Trie(); node = node.children[idx]; } node.isEnd = true; } find(root, word){ let node = root; for(let i=0;i<word.length;i++){ if(node.isEnd) if(this.find(root, word.substring(i, word.length))) return true; const idx = word.charCodeAt(i) - 'a'.charCodeAt(0); if(node.children[idx] === undefined) return false; node = node.children[idx]; } return node.isEnd; } }
java 解法, 执行用时: 37 ms, 内存消耗: 57.9 MB, 提交时间: 2023-10-09 10:33:24
class Solution { Trie trie = new Trie(); public List<String> findAllConcatenatedWordsInADict(String[] words) { List<String> ans = new ArrayList<String>(); Arrays.sort(words, (a, b) -> a.length() - b.length()); for (int i = 0; i < words.length; i++) { String word = words[i]; if (word.length() == 0) { continue; } boolean[] visited = new boolean[word.length()]; if (dfs(word, 0, visited)) { ans.add(word); } else { insert(word); } } return ans; } public boolean dfs(String word, int start, boolean[] visited) { if (word.length() == start) { return true; } if (visited[start]) { return false; } visited[start] = true; Trie node = trie; for (int i = start; i < word.length(); i++) { char ch = word.charAt(i); int index = ch - 'a'; node = node.children[index]; if (node == null) { return false; } if (node.isEnd) { if (dfs(word, i + 1, visited)) { return true; } } } return false; } public void insert(String word) { Trie node = trie; for (int i = 0; i < word.length(); i++) { char ch = word.charAt(i); int index = ch - 'a'; if (node.children[index] == null) { node.children[index] = new Trie(); } node = node.children[index]; } node.isEnd = true; } } class Trie { Trie[] children; boolean isEnd; public Trie() { children = new Trie[26]; isEnd = false; } }
cpp 解法, 执行用时: 340 ms, 内存消耗: 255.1 MB, 提交时间: 2023-10-09 10:32:48
struct Trie { bool isEnd; vector<Trie *> children; Trie() { this->children = vector<Trie *>(26, nullptr); this->isEnd = false; } }; class Solution { public: Trie * trie = new Trie(); vector<string> findAllConcatenatedWordsInADict(vector<string>& words) { vector<string> ans; sort(words.begin(), words.end(), [&](const string & a, const string & b){ return a.size() < b.size(); }); for (int i = 0; i < words.size(); i++) { string word = words[i]; if (word.size() == 0) { continue; } vector<int> visited(word.size(), 0); if (dfs(word, 0, visited)) { ans.emplace_back(word); } else { insert(word); } } return ans; } bool dfs(const string & word, int start, vector<int> & visited) { if (word.size() == start) { return true; } if (visited[start]) { return false; } visited[start] = true; Trie * node = trie; for (int i = start; i < word.size(); i++) { char ch = word[i]; int index = ch - 'a'; node = node->children[index]; if (node == nullptr) { return false; } if (node->isEnd) { if (dfs(word, i + 1, visited)) { return true; } } } return false; } void insert(const string & word) { Trie * node = trie; for (int i = 0; i < word.size(); i++) { char ch = word[i]; int index = ch - 'a'; if (node->children[index] == nullptr) { node->children[index] = new Trie(); } node = node->children[index]; } node->isEnd = true; } };
golang 解法, 执行用时: 92 ms, 内存消耗: 53.6 MB, 提交时间: 2023-10-09 10:32:30
type trie struct { children [26]*trie isEnd bool } func (root *trie) insert(word string) { node := root for _, ch := range word { ch -= 'a' if node.children[ch] == nil { node.children[ch] = &trie{} } node = node.children[ch] } node.isEnd = true } func (root *trie) dfs(vis []bool, word string) bool { if word == "" { return true } if vis[len(word)-1] { return false } vis[len(word)-1] = true node := root for i, ch := range word { node = node.children[ch-'a'] if node == nil { return false } if node.isEnd && root.dfs(vis, word[i+1:]) { return true } } return false } func findAllConcatenatedWordsInADict(words []string) (ans []string) { sort.Slice(words, func(i, j int) bool { return len(words[i]) < len(words[j]) }) root := &trie{} for _, word := range words { if word == "" { continue } vis := make([]bool, len(word)) if root.dfs(vis, word) { ans = append(ans, word) } else { root.insert(word) } } return }
python3 解法, 执行用时: 816 ms, 内存消耗: 34.1 MB, 提交时间: 2023-10-09 10:32:04
class Trie: def __init__(self): self.children = [None] * 26 self.isEnd = False def insert(self, word: str): node = self for ch in word: ch = ord(ch) - ord('a') if not node.children[ch]: node.children[ch] = Trie() node = node.children[ch] node.isEnd = True def dfs(self, word: str, start: int, vis: List[bool]) -> bool: if start == len(word): return True if vis[start]: return False vis[start] = True node = self for i in range(start, len(word)): node = node.children[ord(word[i]) - ord('a')] if node is None: return False if node.isEnd and self.dfs(word, i + 1, vis): return True return False ''' 字典树 + dfs ''' class Solution: def findAllConcatenatedWordsInADict(self, words: List[str]) -> List[str]: words.sort(key=len) ans = [] root = Trie() for word in words: if word == "": continue if root.dfs(word, 0, [False] * len(word)): ans.append(word) else: root.insert(word) return ans