第311场周赛 NO4 字符串的前缀分数和

题目描述:

给你一个长度为 n 的数组 words ,该数组由 非空 字符串组成。

定义字符串 word 的 分数 等于以 word 作为 前缀 的 words[i] 的数目。

例如,如果 words = ["a", "ab", "abc", "cab"] ,那么 "ab" 的分数是 2 ,因为 "ab" 是 "ab" 和 "abc" 的一个前缀。

返回一个长度为 n 的数组 answer ,其中 answer[i] 是 words[i] 的每个非空前缀的分数 总和 。

注意:字符串视作它自身的一个前缀。

LevelAC rate
Hard34.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%的用户

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值