單詞拆分II
阿新 • • 發佈:2021-07-13
這道題考察了dp、字首樹、回溯等知識,下面給出程式碼
class Solution { class TrieNode { String word = null; HashMap<Character, TrieNode> map = new HashMap<>(); public TrieNode() {} } public List<String> wordBreak(String s, List<String> wordDict) { ArrayList<String> res = new ArrayList<>(); // 儲存最終結果 if (s == null || wordDict == null) return res; // 構建字首樹 TrieNode root = new TrieNode(); for (String word : wordDict) { TrieNode node = root; for (Character letter : word.toCharArray()) {if (node.map.containsKey(letter)) { // 如果存在,轉到下一個TrieNode node = node.map.get(letter); } else { // 不存在就建立一個新的TrieNode TrieNode newNode = new TrieNode(); node.map.put(letter, newNode); node = newNode; } } node.word= word; } int[] dp = getDp(s, root); backtrack(s, root, dp, 0, new ArrayList<>(), res); return res; } public void backtrack(String s, TrieNode root, int[] dp, int idx, ArrayList<String> words, ArrayList<String> ans) { if (idx == s.length()) { // 遍歷到最後一個 ans.add(buildToSentence(words)); return; } // 無法分解 if (dp[idx] == 0) return; TrieNode curNode = root; for (int end = idx; end < s.length(); end++) { if (!curNode.map.containsKey(s.charAt(end))) break; curNode = curNode.map.get(s.charAt(end)); if (curNode.word != null) { words.add(s.substring(idx, end + 1)); backtrack(s, root, dp, end + 1, words, ans); words.remove(words.size() - 1); // 回溯 } } } // dp[i]表示s[i...len-1]能被字典所分解的種類數 public int[] getDp(String s, TrieNode root) { int len = s.length(); int[] dp = new int[len+1]; dp[len] = 1; // 空串相當於1個 for (int i = len-1; i >= 0; i--) { TrieNode node = root; int count = 0; for (int j = i; j < len; j++) { if (!node.map.containsKey(s.charAt(j))) break; node = node.map.get(s.charAt(j)); if (node.word != null) count += dp[j+1]; } dp[i] = count; } return dp; } // 將單詞拼接成句子 public String buildToSentence(ArrayList<String> words) { StringBuilder str = new StringBuilder(); for (int idx = 0; idx < words.size(); idx++) { str.append(words.get(idx)); if (idx != words.size() - 1) str.append(" "); } return str.toString(); } }
作者:Ryanjie
出處:http://www.cnblogs.com/ryanjan/
本文版權歸作者和部落格園所有,歡迎轉載。轉載請在留言板處留言給我,且在文章標明原文連結,謝謝!
如果您覺得本篇博文對您有所收穫,覺得我還算用心,請點選右下角的 [推薦],謝謝!