题目描述:
给你一个长度为 n 的数组 words ,该数组由 非空 字符串组成。
定义字符串 word 的 分数 等于以 word 作为 前缀 的 words[i] 的数目。
例如,如果 words = ["a", "ab", "abc", "cab"] ,那么 "ab" 的分数是 2 ,因为 "ab" 是 "ab" 和 "abc" 的一个前缀。
返回一个长度为 n 的数组 answer ,其中 answer[i] 是 words[i] 的每个非空前缀的分数 总和 。
注意:字符串视作它自身的一个前缀。
Level | AC rate |
Hard | 34.2 |
题目解析:
感谢左程云!左神,刚听了前缀树,这次周赛四道题都做出来啦!
使用树的概念来实现字符串及字符串前缀的查找,每个结点的属性设置,pass值,end值,以及长度为26的结点数组来代表26个字母,如果字母对应的结点不为null,代表之前出现过该前缀的字符串,若为null,则根据对应字母new一个node,并将其pass++,如果字符串结束,在对应位置不仅需要pass++还需要end++。
首先我们根据字符串数组中的字符串用来创建前缀树,然后根据pass值和end值来查询某个字符串前缀是否存在,并且存在多少次(根据pass值来看),如果pass值为1,说明目前前缀在整个字符串数组中存在1次,代码如下:
class Solution {
class Node{
public int pass;
public int end;
public Node[] next;
public Node(){
pass = 0;
end = 0;
next = new Node[26];
}
}
Node root;
public int[] sumPrefixScores(String[] words) {
root = new Node();
int[] ans = new int[words.length];
for(int i = 0 ; i<words.length ; i++){
build(words[i]);
}
for(int i = 0 ; i<words.length ; i++){
ans[i] = search(words[i]);
}
return ans;
}
void build(String word){
if(word==null)return;
char[] chs = word.toCharArray();
Node node = root;
node.pass++;
int index = 0;
for(int i = 0 ; i<chs.length ; i++){
index = chs[i]-'a';
if(node.next[index]==null){
node.next[index] = new Node();
}
node = node.next[index];
node.pass++;
}
node.end--;
}
int search(String word){
if(word==null)return 0;
int med = 0;
char[] chs = word.toCharArray();
Node node = root;
int index = 0;
for(int i = 0 ; i<chs.length ; i++){
index = chs[i]-'a';
if(node.next[index]==null){
return 0;
}
med += node.next[index].pass;
node = node.next[index];
}
return med;
}
}
执行用时:511 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:118.7 MB, 在所有 Java 提交中击败了100.00%的用户