在帮助朋友们建立搜索引擎的过程中,小S决定使用倒排索引来提高用户搜索效率。倒排索引的原理是:每个单词关联一个帖子ID的列表,这些帖子包含该单词,且ID按从小到大的顺序排列。问题描述例如,单词“夏天”可能出现在帖子1、帖子3和帖子7中,那么这个单词的倒排链就是 [1, 3, 7]。如果用户想同时找到包含“夏天”和“海滩”的帖子,小S需要找出两个倒排链的交集,并将结果按照从大到小的顺序输出。现在,给定两个单词的倒排链数组 a 和 b,请你帮助小S找出同时包含这两个单词的帖子ID,并按从大到小的顺序返回结果。输入变量说明:
-
a:第一个单词的倒排链数组
-
b:第二个单词的倒排链数组
测试样例样例1:输入:a = [1, 2, 3, 7], b = [2, 5, 7]输出:[7, 2]样例2:输入:a = [1, 4, 8, 10], b = [2, 4, 8, 10]输出:[10, 8, 4]样例3:输入:a = [3, 5, 9], b = [1, 4, 6]输出:[]样例4:输入:a = [1, 2, 3], b = [1, 2, 3]输出:[3, 2, 1]问题分析我们需要找出两个倒排链的交集,并将结果按从大到小的顺序输出。题目中给出的关键信息包括:
-
两个倒排链数组 a 和 b
-
需要找出交集并按降序排列
关键思路
- 求交集:使用集合操作来找出两个数组的交集。
2. 排序:将交集结果按从大到小的顺序排序。代码实现 import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set;
public class InvertedIndexIntersection {
public static List<Integer> findIntersection(int[] a, int[] b) {
// 使用集合来求交集
Set<Integer> setA = new HashSet<>();
for (int num : a) {
setA.add(num);
}
List<Integer> intersection = new ArrayList<>();
for (int num : b) {
if (setA.contains(num)) {
intersection.add(num);
}
}
// 按降序排序
Collections.sort(intersection, Collections.reverseOrder());
return intersection;
}
public static void main(String[] args) {
// 测试样例
System.out.println(findIntersection(new int[]{1, 2, 3, 7}, new int[]{2, 5, 7})); // 输出: [7, 2]
System.out.println(findIntersection(new int[]{1, 4, 8, 10}, new int[]{2, 4, 8, 10})); // 输出: [10, 8, 4]
System.out.println(findIntersection(new int[]{3, 5, 9}, new int[]{1, 4, 6})); // 输出: []
System.out.println(findIntersection(new int[]{1, 2, 3}, new int[]{1, 2, 3})); // 输出: [3, 2, 1]
}
}
代码说明
- 求交集:使用 HashSet 存储第一个数组的元素,然后遍历第二个数组,找出交集。
2. 排序:使用 Collections.sort 方法对交集结果进行降序排序。
深入分析
-
时间复杂度:该算法的时间复杂度为 O(n + m + k log k),其中 n 和 m 是两个数组的长度,k 是交集的大小。求交集的时间复杂度为 O(n + m),排序的时间复杂度为 O(k log k)。
-
空间复杂度:空间复杂度为 O(n + k),因为我们使用了一个集合来存储第一个数组的元素,以及一个列表来存储交集。
可能的优化
在某些情况下,如果两个数组都已经排序,可以使用双指针技术来优化交集的查找过程,从而减少时间复杂度。