[英]What's time complexity of this Algorithm for breaking words? (Dynamic Programming)
分词(使用动态规划:自上而下)
给定一个字符串 s 和一个单词字典 dict,在 s 中添加空格以构造一个句子,其中每个单词都是一个有效的字典单词。返回所有这些可能的句子。
例如,给定
s = "猫砂狗",
dict = ["cat", "cats", "and", "sand", "dog"]。一个解决方案是[“猫和狗”,“猫沙狗”]。
题:
- 时间复杂度 ?
- 空间复杂度 ?
我自己觉得,
- 时间复杂度 = O(n!),不使用动态规划,n 是给定字符串的长度,
- 空间复杂度 = O(n)。
疑惑的:
- 无法计算动态规划的时间复杂度。
- 似乎上面的空间复杂度是不正确的。
代码[Java]
public class Solution {
public List<String> wordBreak(String s, Set<String> dict) {
List<String> list = new ArrayList<String>();
// Input checking.
if (s == null || s.length() == 0 ||
dict == null || dict.size() == 0) return list;
int len = s.length();
// memo[i] is recording,
// whether we cut at index "i", can get one of the result.
boolean memo[] = new boolean[len];
for (int i = 0; i < len; i ++) memo[i] = true;
StringBuilder tmpStrBuilder = new StringBuilder();
helper(s, 0, tmpStrBuilder, dict, list, memo);
return list;
}
private void helper(String s, int start, StringBuilder tmpStrBuilder,
Set<String> dict, List<String> list, boolean[] memo) {
// Base case.
if (start >= s.length()) {
list.add(tmpStrBuilder.toString().trim());
return;
}
int listSizeBeforeRecursion = 0;
for (int i = start; i < s.length(); i ++) {
if (memo[i] == false) continue;
String curr = s.substring(start, i + 1);
if (!dict.contains(curr)) continue;
// Have a try.
tmpStrBuilder.append(curr);
tmpStrBuilder.append(" ");
// Do recursion.
listSizeBeforeRecursion = list.size();
helper(s, i + 1, tmpStrBuilder, dict, list, memo);
if (list.size() == listSizeBeforeRecursion) memo[i] = false;
// Roll back.
tmpStrBuilder.setLength(tmpStrBuilder.length() - curr.length() - 1);
}
}
}
是动态问题。
你可以维护两件事。
1 DP[i] 表示当字符串在第 i 个字符中时,有 dp[i] 种方式来切割它。
2 vector < int> pre[i] 表示前一个位置可以到达当前第i个位置。(它的大小必须是DP[i])
时间是 O(n*m)
首先,我在 [0,n) 中:
然后在 [0,i) 中找到 j:那个子串(j+1,i) 是有效的。
验证可以预先计算。 所以时间是O(n*m),你可以用vector < int> pre[i] 得到你想要的所有切割解。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.