题目对应LeetCode
139. 单词拆分
1. 题目描述
给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
示例 1:
输入: s = “leetcode”, wordDict = [“leet”, “code”]
输出: true
解释: 返回 true 因为 “leetcode” 可以由 “leet” 和 “code” 拼接成。
示例 2:
输入: s = “applepenapple”, wordDict = [“apple”, “pen”]
输出: true
解释: 返回 true 因为 “applepenapple” 可以由 “apple” “pen” “apple” 拼接成。
注意,你可以重复使用字典中的单词。
示例 3:
输入: s = “catsandog”, wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]
输出: false
2. 代码分析
【动态规划】+【字典树】
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 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| class Solution { public boolean wordBreak(String s, List<String> wordDict) { Trie root = build(wordDict); int n = s.length(); boolean[] dp = new boolean[n]; for (int i=0; i<n; i++) { List<Integer> list = check(s, root, i); for (int idx : list) { if (idx==0 || dp[idx-1]) { dp[i] = true; } } } return dp[n-1]; }
public List<Integer> check(String s, Trie root, int lastIndex) { Trie node = root; List<Integer> list = new ArrayList<>(); while (lastIndex >= 0) { int index = s.charAt(lastIndex) - 'a'; if (node.children[index] == null) { break; } node = node.children[index]; if (node.isEnd) { list.add(lastIndex); } lastIndex--; } return list; }
public Trie build(List<String> wordDict) { Trie root = new Trie(); for (String s : wordDict) { Trie node = root; for (int i=s.length()-1; i>=0; i--) { int idx = s.charAt(i)-'a'; if (node.children[idx] == null) { node.children[idx] = new Trie(); } node = node.children[idx]; } node.isEnd = true; } return root; } }
class Trie{ Trie[] children; boolean isEnd;
public Trie() { children = new Trie[26]; } }
|