题目链接
思路
这道题关键在于求 以前缀prefix开头的键key的值的总和,可以用前缀树结点存放val来解决 具体操作为:给前缀树的结点增设一个val属性,通过key建立前缀树时把每一个经过的结点加上value 在求总和时只需要遍历prefix,然后返回最终结点的val即可~ 比如首先输入[“apple”, 3] 我们首先建立前缀树,然后把每个结点(a p p l e)的val都置为3,然后再输入[“app”, 2],我们再把前三个结点(a p p)的val+2,这样最终的结点和对应的值分别为(a:5 p:5 p:5 l:3 e:3)。如果输入前缀为ap,那么我们就遍历到第一个p,然后返回他的val 5 这样有一个致命的缺陷在于,如果更新val,结点的和不会更新,只会增加。但是我们可以通过增加一个HashMap来改进建立前缀树的过程。在输入一个key时,我们首先查表,如果能找到它原先的val值,我们就在结点增加完val后再减去原先的val,这样就实现了更新目的~
class MapSum {
class TrieNode {
int value;
TrieNode [ ] children;
TrieNode ( ) {
value = 0 ;
children = new TrieNode [ 26 ] ;
}
}
private TrieNode root;
Map < String , Integer > map;
public MapSum ( ) {
root = new TrieNode ( ) ;
map = new HashMap < > ( ) ;
}
public void insert ( String key, int val) {
int delta = val - map. getOrDefault ( key, 0 ) ;
map. put ( key, val) ;
TrieNode cur = root;
for ( char ch : key. toCharArray ( ) ) {
if ( null == cur. children[ ch - 'a' ] )
cur. children[ ch - 'a' ] = new TrieNode ( ) ;
cur = cur. children[ ch - 'a' ] ;
cur. value += val - delValue;
}
}
public int sum ( String prefix) {
TrieNode cur = root;
for ( char ch : prefix. toCharArray ( ) ) {
if ( null == cur. children[ ch - 'a' ] )
return 0 ;
cur = cur. children[ ch - 'a' ] ;
}
return cur. value;
}
}
补充一下作者的思路
他选择在单词的末端保存val值,因此每次insert时值都会被覆盖~ 不再需要用哈希表保存原先的val 然后在求sum时先遍历到prefix的末尾结点,然后遍历这个结点的所有子树,返回所有叶子结点的val和~ 还是觉得我的思路好 b( ̄▽ ̄)d