3、前缀树
模板
import java.util.LinkedList;
import java.util.List;
public class TrieMap<V> {
private static final int R = 256;
private static int size = 0;
private TrieNode<V> root = null;
private static class TrieNode<V> {
V val = null;
TrieNode<V>[] children = new TrieNode[R];
}
public TrieNode<V> put(String key, V val) {
if (!containsKey(key)) {
size++;
}
root = put(root, key, val, 0);
return root;
}
private TrieNode<V> put(TrieNode<V> node, String key, V val, int i) {
if (node == null) {
node = new TrieNode<>();
}
if (i == key.length()) {
node.val = val;
return node;
}
char c = key.charAt(i);
node.children[c] = put(node.children[c], key, val, i + 1);
return node;
}
public TrieNode<V> remove(String key) {
if (!containsKey(key)) {
return null;
}
root = remove(root, key, 0);
return root;
}
private TrieNode<V> remove(TrieNode<V> node, String key, int i) {
if (node == null) {
return null;
}
if (i == key.length()) {
node.val = null;
return null;
}
char c = key.charAt(i);
node.children[c] = remove(node.children[c], key, i + 1);
if (node.val != null) {
return node;
}
for (char d = 0; d < R; d++) {
if (node.children[d] != null) {
return node;
}
}
return null;
}
private TrieNode<V> getNode(TrieNode node, String key) {
TrieNode p = node;
for (int i = 0; i < key.length(); i++) {
if (p == null) {
return null;
}
char c = key.charAt(i);
p = p.children[c];
}
return p;
}
public V get(String key) {
TrieNode<V> x = getNode(root, key);
if (x != null && x.val != null) {
return x.val;
}
return null;
}
public boolean containsKey(String key) {
return get(key) != null;
}
public boolean containsPrefix(String prefix) {
return getNode(root, prefix) != null;
}
public String shortestPrefix(String query) {
TrieNode<V> p = this.root;
for (int i = 0; i < query.length(); i++) {
if (p == null) {
return null;
}
if (p.val != null) {
return query.substring(0, i);
}
char c = query.charAt(i);
p = p.children[c];
}
if (p != null && p.val != null) {
return query;
}
return null;
}
public String longestPrefix(String query) {
TrieNode<V> p = this.root;
int max_len = 0;
for (int i = 0; i < query.length(); i++) {
if (p == null) {
break;
}
if (p.val != null) {
max_len = i;
}
char c = query.charAt(i);
p = p.children[c];
}
if (p != null && p.val != null) {
return query;
}
return query.substring(0, max_len);
}
public List<String> keysWithPrefixOf(String prefix) {
List<String> res = new LinkedList<>();
TrieNode<V> x = getNode(root, prefix);
traverse(x, new StringBuffer(prefix), res);
return res;
}
private void traverse(TrieNode<V> node, StringBuffer path, List<String> res) {
if (node == null) {
return;
}
if (node.val != null) {
res.add(path.toString());
}
for (char c = 0; c < R; c++) {
path.append(c);
traverse(node.children[c], path, res);
path.deleteCharAt(path.length() - 1);
}
}
public List<String> keysWithPattern(String pattern) {
List<String> res = new LinkedList<>();
traverse(root, new StringBuffer(), res, pattern, 0);
return res;
}
private void traverse(TrieNode<V> node, StringBuffer path, List<String> res, String pattern, int i) {
if (node == null) {
return;
}
if (i == pattern.length()) {
if (node.val != null) {
res.add(path.toString());
}
return;
}
char c = pattern.charAt(i);
if (c == '.') {
for (char d = 0; d < R; d++) {
path.append(d);
traverse(node.children[d], path, res, pattern, i + 1);
path.deleteCharAt(path.length() - 1);
}
} else {
path.append(c);
traverse(node.children[c], path, res, pattern, i + 1);
path.deleteCharAt(path.length() - 1);
}
}
public boolean hasKeyWithPattern(String pattern) {
return traverse(root, pattern, 0);
}
private boolean traverse(TrieNode<V> node, String pattern, int i) {
if (node == null) {
return false;
}
if (i == pattern.length()) {
if (node.val != null) {
return true;
}
return false;
}
char c = pattern.charAt(i);
if (c == '.') {
for (char d = 97; d < 97 + 26; d++) {
if (node.children[d] != null) {
if (traverse(node.children[d], pattern, i + 1)) return true;
}
}
} else {
if (traverse(node.children[c], pattern, i + 1)) return true;
}
return false;
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jo6nwjY2-1648990807585)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/13ecf4ef-9d7e-49a7-b671-71b09b28adeb/Untitled.png)]
### 解题思路
此处撰写解题思路
### 代码
```java
class Trie {
private final TrieMap<Object> map = new TrieMap<>();
public Trie() {
}
public void insert(String word) {
map.put(word, new Object());
}
public boolean search(String word) {
return map.containsKey(word);
}
public boolean startsWith(String prefix) {
return map.containsPrefix(prefix);
}
}
class Solution {
private TrieMap<Object> map = new TrieMap<Object>();
public String replaceWords(List<String> dictionary, String sentence) {
for (int i = 0; i < dictionary.size(); i++) {
map.put(dictionary.get(i), new Object());
}
String[] split = sentence.split("\\s+");
StringBuffer sb = new StringBuffer();
for (int i = 0; i < split.length; i++) {
String str = map.shortestPrefix(split[i]);
if (str == null) {
sb.append(split[i]);
} else {
sb.append(str);
}
if (i != split.length - 1) {
sb.append(' ');
}
}
return sb.toString();
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q3xxG673-1648990807586)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/d81bee25-ab40-410d-b47f-064e9305fe39/Untitled.png)]
class WordDictionary {
TrieMap<Object> map = new TrieMap<>();
public WordDictionary() {
}
public void addWord(String word) {
map.put(word, new Object());
}
public boolean search(String word) {
return map.hasKeyWithPattern(word);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OZPeg37C-1648990807587)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/47375219-2b43-47a7-9f4e-b4ba187105c2/Untitled.png)]
class MapSum {
TrieMap<Integer> map;
public MapSum() {
map = new TrieMap<>();
}
public void insert(String key, int val) {
map.put(key, val);
}
public int sum(String prefix) {
List<String> list = map.keysWithPrefixOf(prefix);
int sum = 0;
for (String s : list) {
Integer x = map.get(s);
sum += x;
}
return sum;
}
}
|