139. 单词拆分
给你一个字符串 s
和一个字符串列表 wordDict
作为字典。请你判断是否可以利用字典中出现的单词拼接出 s
。
**注意:**不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
示例 1:
1 2 3
| 输入: s = "leetcode", wordDict = ["leet", "code"] 输出: true 解释: 返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。
|
示例 2:
1 2 3 4
| 输入: s = "applepenapple", wordDict = ["apple", "pen"] 输出: true 解释: 返回 true 因为 "applepenapple" 可以由 "apple" "pen" "apple" 拼接成。 注意,你可以重复使用字典中的单词。
|
示例 3:
1 2
| 输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"] 输出: false
|
提示:
1 <= s.length <= 300
1 <= wordDict.length <= 1000
1 <= wordDict[i].length <= 20
s
和 wordDict[i]
仅由小写英文字母组成
wordDict
中的所有字符串 互不相同
字典树+记忆化搜索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| class Trie { class TrieNode { boolean end; TrieNode[] children = new TrieNode[26]; } TrieNode root = new TrieNode(); void insert(String word) { TrieNode cur = root; for (char c : word.toCharArray()) { int index = (int) c - 97; if (cur.children[index] == null) { cur.children[index] = new TrieNode(); } cur = cur.children[index]; } cur.end = true; } boolean search(String word) { TrieNode cur = root; for (char c : word.toCharArray()) { int index = (int) c - 97; if (cur.children[index] == null) return false; cur = cur.children[index]; } return cur.end; } }
class Solution { Trie trie = new Trie(); boolean[] fail = new boolean[301]; public boolean search(String s, int start) { if (fail[start]) return false; int len = s.length(); if (start >= len) return true; Trie.TrieNode cur = trie.root; for (int i = start; i < len; i++) { int index = s.charAt(i) - 97; if (cur.children[index] == null) return false; cur = cur.children[index]; if (cur.end) { if (search(s, i + 1)) return true; else fail[i + 1] = true; } } return false; }
public boolean wordBreak(String s, List<String> wordDict) { int n = wordDict.size(); for (int i = 0; i < n; ++i) { String word = wordDict.get(i); trie.insert(word); } return search(s, 0); } }
|