LeetCode Word Break & Word Break II
2015-02-09 12:33
441 查看
Word Break
题意:给定一个字符串str,和一个集合dict,问能否用集合当中的字符串(可以使用多次)拼接处str解法:动态规划dp[i]表示当前i前面的下标能否被拼接而成
刚刚开始都会想到一个比较朴素的想法是
for (int i=1; i<=l; i++)
while (ite.hasNext())
……
但是后来发现貌似不用遍历dict,而是枚举任意两个的起始点和终点,然后判断当前这个字符串是否在dict当中出现过
for (int i=1; i<=l; i++)
for (int j=i-1;j>=0; j--)
……
两个方法都可以,但是明显第二个编写比较简单。复杂度上,第一个是O(L^2),第二个是O(LM),其中L是字符串的长度,而M是dict几何所包含的字符串个数。
import java.util.*; public class Solution { public boolean wordBreak(String s, Set<String> dict) { int l = s.length(); boolean dp[] = new boolean[l + 1]; Arrays.fill(dp, false); dp[0] = true; for (int i = 1; i <= l; i++) { for (int j = i - 1; j >= 0; j--) { if (dp[j] && dict.contains(s.substring(j, i))) { dp[i] = true; } } } return dp[l]; } public static void main(String[] args) { Solution s = new Solution(); String str = "abcde"; Set<String> dict = new HashSet<String>(); dict.add("a"); dict.add("abc"); dict.add("b"); dict.add("cd"); System.out.println(s.wordBreak(str, dict)); } }
Word Break II
题意:比上一个返回条件复杂了一点,要求返回所以可能的情况……其实还是dp就可以解法一:
第一种解法和上面的类似,还是dp,只不过用一个HashMap记录了一下当前所有情况的结果
代码如下(TLE了)
import java.util.*; public class Solution { public List<String> wordBreak(String s, Set<String> dict) { int l = s.length(); boolean dp[] = new boolean[l + 1]; dp[0] = true; HashMap<Integer, LinkedList<String>> map = new HashMap<Integer, LinkedList<String>>(); for (int i = 0; i <= l; i++) map.put(i, new LinkedList<String>()); map.get(0).add(""); LinkedList<String> listI, listJ; String first, second; for (int i = 1; i <= l; i++) { listI = map.get(i); for (int j = i - 1; j >= 0; j--) { if (dp[j] && dict.contains(s.substring(j, i))) { dp[i] = true; second = s.substring(j, i); if (j == 0) { listI.add(second); } else { listJ = map.get(j); Iterator<String> ite = listJ.iterator(); while (ite.hasNext()) { first = ite.next(); listI.add(first + " " + second); } } } } } return map.get(l); } }
解法二:
从前往后暴力搜索或者归溯法记忆化搜索,不过后者比较好费空间。
纯暴力在这里会TLE,可以先判断是否能够break,因为给的测试数据很多是不可行的,不过稍微有些赖皮的方法。
import java.util.*; public class Solution { public ArrayList<String> list; public String string; public Set<String> set; public ArrayList<String> wordBreak(String s, Set<String> dict) { list = new ArrayList<String>(); if (s == null || s.length() == 0) return list; if (!wordBreakOK(s, dict)) return list; string = s; set = dict; dfs(0, ""); return list; } public boolean wordBreakOK(String s, Set<String> dict) { int l = s.length(); boolean dp[] = new boolean[l + 1]; Arrays.fill(dp, false); dp[0] = true; for (int i = 1; i <= l; i++) { for (int j = i - 1; j >= 0; j--) { if (dp[j] && dict.contains(s.substring(j, i))) { dp[i] = true; } } } return dp[l]; } public void dfs(int start, String temp) { if (start == string.length()) { list.add(temp); return; } for (int i = start + 1; i <= string.length(); i++) { if (set.contains(string.substring(start, i))) { if (start > 0) dfs(i, temp + " " + string.substring(start, i)); else dfs(i, string.substring(start, i)); } } } public static void main(String[] args) { Solution s = new Solution(); String str = "abcd"; Set<String> dict = new HashSet<String>(); dict.add("a"); dict.add("abc"); dict.add("b"); dict.add("cd"); dict.add("d"); System.out.println(s.wordBreak(str, dict)); } }
相关文章推荐
- [C++]LeetCode: 113 Word Break II (DP && Backtacking) 求解拆分组合
- LeetCode ||& Word Break && Word Break II(转)——动态规划
- LeetCode: Word Break I && II
- 【leetcode】Word Break && Word Break II
- 【LeetCode】word break I && II
- Leetcode 139&140. Word Break I & II
- leetcode做题总结,回溯法(N-Queens, N-QueensII,Combination SumI&II,wordbreak II, SubsetsI&II)
- Leetcode 139. Word Break & 140. Word Break II
- Leetcode 139. Word Break I&&II
- LeetCode之“动态规划”:Word Break && Word Break II
- [LeetCode] Word Break && Word Break II
- leetCode: Word Break I & Word Break II
- [Leetcode]Word Break & Word Break II
- 【LeetCode】Word Break && Word Break II
- leetcode word break I && II
- leetcode -- Word Break I & II -- 重点
- leetcode Word Break I II 算法分析
- LeetCode - Word Break II
- Leetcode Word Break II
- [LeetCode] - Word Break II