【211】添加与搜索单词–数据结构设计
设计一个支持以下两种操作的数据结构:
void addWord(word)
bool search(word)
search(word) 可以搜索文字或正则表达式字符串,字符串只包含字母 . 或 a-z 。 . 可以表示任何一个字母。
示例:
addWord(“bad”)
addWord(“dad”)
addWord(“mad”)
search(“pad”) -> false
search(“bad”) -> true
search(".ad") -> true
search(“b…”) -> tru
思路:这里运用我们之前的字典树可以很好解决,要注意的是这个“.”可以表示任何字母,所以要作判断
public class WordDictionary {
private class Node{//这里调用字典树的结点类
public boolean isWord;
public TreeMap<Character, Node> next;
public Node(boolean isWord){
this.isWord = isWord;
next = new TreeMap<>();
}
public Node(){
this(false);
}
}
private Node root;
/** Initialize your data structure here. */
public WordDictionary() {
root = new Node();
}
/** Adds a word into the data structure. */
public void addWord(String word) {//添加操作无变化
Node cur = root;
for(int i = 0 ; i < word.length() ; i ++){
char c = word.charAt(i);
if(cur.next.get(c) == null)
cur.next.put(c, new Node());
cur = cur.next.get(c);
}
cur.isWord = true;
}
/** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
public boolean search(String word) {//查找操作调用递归
return match(root, word, 0);
}
private boolean match(Node node, String word, int index){
if(index == word.length())//递归终止条件,整个字符串考虑完了,只需要看当前节点标识符
return node.isWord;
char c = word.charAt(index);
if(c != '.'){//如果c为字母
if(node.next.get(c) == null)//不包含该字母
return false;
return match(node.next.get(c), word, index + 1);
//包含该字母,递归下一个节点去匹配,继续匹配后面的部分
}
else{
for(char nextChar: node.next.keySet())//将Trie中所有可以映射的字符取出来,都尝试匹配C代表的这个“.”
if(match(node.next.get(nextChar), word, index + 1)//匹配完这个“.”之后,继续从nextchar这个节点继续匹配
return true;
return false;
}
}
}
【677】键值映射
实现一个 MapSum 类里的两个方法,insert 和 sum。
对于方法 insert,你将得到一对(字符串,整数)的键值对。字符串表示键,整数表示值。如果键已经存在,那么原来的键值对将被替代成新的键值对。
对于方法 sum,你将得到一个表示前缀的字符串,你需要返回所有以该前缀开头的键的值的总和。
示例 1:
输入: insert(“apple”, 3), 输出: Null
输入: sum(“ap”), 输出: 3
输入: insert(“app”, 2), 输出: Null
输入: sum(“ap”), 输出: 5
public class MapSum {
private class Node{
public int value;
public TreeMap<Character, Node> next;
public Node(int value){
this.value = value;
next = new TreeMap<>();
}
public Node(){
this(0);
}
}
private Node root;
/** Initialize your data structure here. */
public MapSum() {
root = new Node();
}
public void insert(String key, int val) {
Node cur = root;
for(int i = 0 ; i < key.length() ; i ++){
char c = key.charAt(i);
if(cur.next.get(c) == null)
cur.next.put(c, new Node());
cur = cur.next.get(c);
}
cur.value = val;//给单词赋值val
}
public int sum(String prefix) {
Node cur = root;
for(int i = 0 ; i < prefix.length() ; i ++){
char c = prefix.charAt(i);
if(cur.next.get(c) == null)
return 0;
cur = cur.next.get(c);
}
return sum(cur);
}
private int sum(Node node){//前缀最后一个字母所在的节点
int res = node.value;//这里是以防前缀也是一个单词,也有val
for(char c: node.next.keySet())//将所有以该前缀开头的键取出
res += sum(node.next.get(c));//将对应的val全部相加
return res;
}
}