如何实现基于树索引的不可比较元素列表intercalate方法?
解决方案
核心思路是:利用TreeVector提供的方法获取每个叶子节点的索引,基于索引对两个列表的元素进行排序合并,而非依赖LinkedList的动态插入操作。
步骤1:建立元素与索引的映射
通过TreeVector的相关方法(比如假设存在getLeafIndex(Leaf leaf)方法),为两个输入列表中的每个元素获取对应的叶子节点索引。由于元素本身就是树的叶子节点,可直接将元素转为Leaf类型调用方法。
步骤2:合并并排序元素
以下两种实现方式可根据元素数量规模选择:
方式一:统一收集后排序
实现简单,适合元素数量不大的场景:
- 将两个列表的元素与对应索引打包成键值对。
- 将所有键值对放入集合,按索引升序排序。
- 遍历排序后的集合,提取元素组成结果列表。
示例代码(Java):
import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.AbstractMap.SimpleEntry; public class TreeMerger { private TreeVector treeVector; public TreeMerger(TreeVector treeVector) { this.treeVector = treeVector; } public List<Leaf> intercalate(List<Leaf> xs, List<Leaf> ys) { // 打包元素与索引 List<Map.Entry<Integer, Leaf>> indexedElements = new ArrayList<>(); for (Leaf leaf : xs) { int index = treeVector.getLeafIndex(leaf); indexedElements.add(new SimpleEntry<>(index, leaf)); } for (Leaf leaf : ys) { int index = treeVector.getLeafIndex(leaf); indexedElements.add(new SimpleEntry<>(index, leaf)); } // 按索引排序 indexedElements.sort(Comparator.comparingInt(Map.Entry::getKey)); // 提取结果 List<Leaf> result = new ArrayList<>(); for (Map.Entry<Integer, Leaf> entry : indexedElements) { result.add(entry.getValue()); } return result; } }
方式二:先分别排序再归并合并
适合元素数量较大的场景,可减少内存占用:
- 对
xs列表按元素索引升序排序。 - 对
ys列表按元素索引升序排序。 - 用双指针遍历两个已排序列表,每次选择索引较小的元素加入结果;遍历完一个列表后,将另一个列表的剩余元素全部加入。
示例代码(Java):
import java.util.ArrayList; import java.util.Comparator; import java.util.List; public class TreeMerger { private TreeVector treeVector; public TreeMerger(TreeVector treeVector) { this.treeVector = treeVector; } public List<Leaf> intercalate(List<Leaf> xs, List<Leaf> ys) { // 单独排序两个列表 xs.sort(Comparator.comparingInt(treeVector::getLeafIndex)); ys.sort(Comparator.comparingInt(treeVector::getLeafIndex)); // 归并合并 List<Leaf> result = new ArrayList<>(); int i = 0, j = 0; while (i < xs.size() && j < ys.size()) { Leaf x = xs.get(i); Leaf y = ys.get(j); int idxX = treeVector.getLeafIndex(x); int idxY = treeVector.getLeafIndex(y); if (idxX < idxY) { result.add(x); i++; } else { result.add(y); j++; } } // 加入剩余元素 result.addAll(xs.subList(i, xs.size())); result.addAll(ys.subList(j, ys.size())); return result; } }
为什么LinkedList不适合?
LinkedList的插入操作需要先遍历找到插入位置,若元素索引无序,每次插入的时间复杂度为O(n),整体会达到O(n²),效率极低。而先通过索引排序再构建结果的方式,时间复杂度由排序决定(O(n log n)),性能更优。
内容的提问来源于stack exchange,提问作者Javier Montes Pérez
相关产品推荐
相关产品推荐

