存储大量集合高效计算元素值总和,求最优数据结构与算法建议
推荐数据结构与算法方案
一、推荐数据结构:前缀树(Trie)
针对存在大量公共子序列的集合场景,**前缀树(Trie)**是最优选择之一,核心思路是让共享相同元素前缀的集合复用存储结构与计算结果:
结构设计:
- 给每个元素分配唯一ID(如0到M-1,M为元素总数),将所有集合的元素转换为有序ID列表(按ID升序排列,确保相同元素组合的路径一致)。
- Trie的每个节点包含:
- 子节点映射:键为元素ID,值为对应子节点
- 标记位:标识该节点是否是某个完整集合的终点
- 累计总和:存储从根节点到当前节点的元素X值之和(输入X后计算)
优势:
- 空间优化:共享公共前缀的集合无需重复存储元素,大幅降低空间复杂度(从最坏O(T)降至O(U),U为Trie中唯一节点数,U≤T,T为所有集合的元素总个数)
- 计算复用:输入X值后,仅需遍历Trie一次即可完成所有集合的总和计算,避免重复计算公共子序列的和
二、求和与找最大值算法步骤
离线预处理(集合结构构建)
- 为每个元素分配唯一ID,将所有集合转换为升序排列的ID列表;
- 构建Trie树:遍历每个有序ID列表,从根节点开始依次添加元素节点,若节点已存在则直接复用,否则创建新节点;标记每个集合的终点节点。
在线计算(输入X值后)
- 用数组存储元素ID到X值的映射(因ID连续,数组效率高于哈希表);
- 遍历Trie树,递归/迭代计算每个节点的累计总和:当前节点总和 = 父节点总和 + 当前元素的X值(根节点总和为0);
- 遍历过程中记录所有终点节点的最大总和,以及对应的集合(若需输出集合,可在终点节点存储集合的原始标识或路径)。
三、时间复杂度分析
- 离线预处理:O(N*K log K),其中N为集合总数,K为单个集合的平均元素个数(主要耗时在集合元素排序);
- 在线计算:O(U),U为Trie树的节点总数(最坏等于所有集合的元素总个数T,最优情况下因共享前缀远小于T);
- 整体时间复杂度优于直接遍历每个集合计算总和的O(T)(当存在大量公共子序列时,U<<T)。
示例验证
针对题目中的示例:
- 元素ID分配:A=0, B=1, C=2, D=3, E=4
- 集合转换为有序ID列表:
- (A,B) → [0,1]
- (C,D) → [2,3]
- (B,C,E) → [1,2,4]
- (B,D,E) → [1,3,4]
- (A,C,D,E) → [0,2,3,4]
- 构建Trie后,输入X值[0.2,0.8,0.6,0.3,0.5],遍历计算各终点节点总和:
- [0,1]总和:0.2+0.8=1.0
- [2,3]总和:0.6+0.3=0.9
- [1,2,4]总和:0.8+0.6+0.5=1.9
- [1,3,4]总和:0.8+0.3+0.5=1.6
- [0,2,3,4]总和:0.2+0.6+0.3+0.5=1.6
- 最大总和为1.9,对应集合(B,C,E),与示例结果一致。
内容的提问来源于stack exchange,提问作者tenacity
相关产品推荐
相关产品推荐

