- 方法一(暴力法)
遍历sentence字符串中的所有可能的子串,并将每个子串与
dictinary数组中的每个单词比较,若相等,则说明这个子串已被识别,dp数组中对应位置的大小可以减掉对应的单词长度,即 dp[i] = dp[i-word.length()]
。
class Solution {
public int respace(String[] dictionary, String sentence) {
int slen = sentence.length();
int[] dp = new int[slen+1];
dp[0] = 0;
for(int i=1; i<=slen; i++){
dp[i] = dp[i-1]+1;
for(String str : dictionary){
int len = str.length();
if(len<=i && str.equals(sentence.substring(i-len, i))){
dp[i] = Math.min(dp[i], dp[i-len]);
}
}
}
return dp[slen];
}
}
- 方法二(字典树)
利用字典树优化单词的搜索过程,字典树是以单词的字母来对单词进行排序从而生成一个查找树。因此单词的搜索时间复杂度可以优化为O(nlogn)。
class Solution {
public int respace(String[] dictionary, String sentence) {
int n = sentence.length();
Trie root = new Trie();
for (String word: dictionary) {
root.insert(word);
}
int[] dp = new int[n + 1];
dp[0] = 0;
for (int i = 1; i <= n; ++i) {
dp[i] = dp[i - 1] + 1;
Trie curPos = root;
for (int j = i; j >= 1; --j) {
int t = sentence.charAt(j - 1) - 'a';
if (curPos.next[t] == null) {
break;
} else if (curPos.next[t].isEnd) {
dp[i] = Math.min(dp[i], dp[j - 1]);
}
if (dp[i] == 0) {
break;
}
curPos = curPos.next[t];
}
}
return dp[n];
}
}
class Trie {
public Trie[] next;
public boolean isEnd;
public Trie() {
next = new Trie[26];
isEnd = false;
}
public void insert(String s) {
Trie curPos = this;
for (int i = s.length() - 1; i >= 0; --i) {
int t = s.charAt(i) - 'a';
if (curPos.next[t] == null) {
curPos.next[t] = new Trie();
}
curPos = curPos.next[t];
}
curPos.isEnd = true;
}
}