LC.P2707[字符串中的额外字符]

方法一:哈希表+动态规划

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public int minExtraChar(String s, String[] dictionary) {
Set<String> set = new HashSet<>();
for (String w : dictionary) {
set.add(w);
}
int n = s.length();
int[] f = new int[n + 1];
f[0] = 0;
for (int i = 1; i <= n; ++i) {
f[i] = f[i - 1] + 1;
for (int j = 0; j < i; ++j) {
if (set.contains(s.substring(j, i))) {
f[i] = Math.min(f[i], f[j]);
}
}
}
return f[n];
}
}
  • 时间复杂度:$O(n^3 + L)$,$L$为字典中所有单词长度之和
  • 空间复杂度:$O(n + L)$

方法二:字典树+动态规划

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
class Solution {
public int minExtraChar(String s, String[] dictionary) {
Trie trie = new Trie();
for (String word : dictionary) {
trie.insert(word);
}
int n = s.length();
int[] f = new int[n + 1];
for (int i = 1; i <= n; ++i) {
f[i] = f[i - 1] + 1;
Trie node = trie;
for (int j = i - 1; j >= 0; --j) {
node = node.children[s.charAt(j) - 'a'];
if (node == null) break;
if (node.isEnd && f[j] < f[i]) {
f[i] = f[j];
}
}
}
return f[n];
}

private static class Trie {
Trie[] children;
boolean isEnd;

public Trie() {
children = new Trie[26];
isEnd = false;
}

public void insert(String word) {
Trie node = this;
for (int i = word.length() - 1; i >= 0; --i) {
int idx = word.charAt(i) - 'a';
if (node.children[idx] == null) {
node.children[idx] = new Trie();
}
node = node.children[idx];
}
node.isEnd = true;
}
}
}
  • 时间复杂度:$O(n^2 + L)$
  • 空间复杂度:$O(n + L \times C)$,$C = 26$