leetcode
leetcode 2101 ~ 2150
字符串的前缀分数和

字符串的前缀分数和

难度:

标签:

题目描述

代码结果

运行时间: 1308 ms, 内存: 202.7 MB


/*
 * 题目思路:
 * 1. 使用 Java Stream 来计算前缀的出现次数。
 * 2. 计算每个单词的前缀分数总和。
 */
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class SolutionStream {
    public int[] prefixScores(String[] words) {
        Map<String, Long> prefixCount = Arrays.stream(words)
                .flatMap(word -> IntStream.rangeClosed(1, word.length()).mapToObj(i -> word.substring(0, i)))
                .collect(Collectors.groupingBy(prefix -> prefix, Collectors.counting()));

        return Arrays.stream(words)
                .mapToInt(word -> IntStream.rangeClosed(1, word.length())
                        .map(i -> prefixCount.get(word.substring(0, i)).intValue())
                        .sum())
                .toArray();
    }

    public static void main(String[] args) {
        SolutionStream sol = new SolutionStream();
        String[] words = {"abc", "ab", "bc", "b"};
        int[] result = sol.prefixScores(words);
        Arrays.stream(result).forEach(System.out::println);
    }
}

解释

方法:

这道题目可以通过使用字典树(Trie)的数据结构来高效解决。首先,构建一个字典树,其中每个节点存储了到当前节点为止的字符串前缀出现的次数。这样,当再次遍历每个单词的每个前缀时,可以直接从字典树中获取该前缀出现的次数,从而计算出每个单词的前缀分数和。具体步骤包括:1. 构建字典树,记录每个前缀出现的次数。2. 对每个单词,查询其所有前缀在字典树中的出现次数,并累加得到该单词的前缀分数和。

时间复杂度:

O(n*L)

空间复杂度:

O(n*L)

代码细节讲解

🦆
在构建字典树时,如何确保每个节点准确记录下到该节点为止的字符串前缀出现的次数?
在构建字典树的过程中,每次插入一个单词的字符时,都会沿着字典树的路径向下走。对于每个字符,如果该字符对应的节点已经存在,则将该节点的计数器(通常用 '#' 键来表示)增加 1,表示该前缀的出现次数增加了 1。如果该字符对应的节点不存在,则创建一个新的节点,并初始化计数器为 1。这样,每个节点的计数器都准确地表示从根节点到该节点的路径(即前缀)在所有插入的单词中出现的次数。
🦆
在字典树的实现中,'#'键所存储的值具体代表了什么?
'#'键在字典树的节点中用于存储到达该点的路径(即前缀)在插入的所有单词中出现的次数。每次插入一个单词或前缀时,沿途访问的每个节点的'#'键的值都会增加,从而确保可以快速查询任何前缀的出现频率。
🦆
如何处理字典树中的边界情况,比如单词全部由相同字符组成的情况?
字典树天然适合处理包含重复字符的单词。即使单词由相同的字符组成,构建过程仍然是将每个字符按顺序插入字典树。对于这样的单词,字典树将形成一个单一分支的结构,每个节点代表重复字符的一个实例,并且节点的'#'键会正确统计到达该节点的前缀在所有单词中出现的次数。这保证了即使是重复字符构成的单词也能正确处理和计算前缀分数。
🦆
在对单词进行前缀分数计算时,是否有可能出现访问字典树中未定义的节点的情况?如果有,该如何预防?
在理论上,如果字典树构建正确且所有需要计算前缀分数的单词都是先前已经插入到字典树中的,那么就不会出现访问未定义节点的情况。然而,如果存在试图查询未经插入的单词的前缀,这将导致尝试访问未定义的节点。为预防这种情况,可以在访问节点前增加检查,确保该节点存在。如果节点不存在,则可以停止处理当前单词并返回错误或零,或者在设计时确保所有查询的单词都已经在字典树中。

相关问题