题目解析:小S的倒排索引
小S正在帮助她的朋友们建立一个搜索引擎。为了让用户能够更快地找到他们感兴趣的帖子,小S决定使用倒排索引。倒排索引的工作原理是:每个单词都会关联一个帖子ID的列表,这些帖子包含该单词,且ID按从小到大的顺序排列。
例如,单词“夏天”可能出现在帖子1、帖子3和帖子7中,那么这个单词的倒排链就是 [1, 3, 7]。如果用户想同时找到包含“夏天”和“海滩”的帖子,小S需要找出两个倒排链的交集,且将结果按照从大到小的顺序输出。现在,给定两个单词的倒排链数组 a 和 b,请你帮助小S找出同时包含这两个单词的帖子ID,并按从大到小的顺序返回结果。
解题思路分析
测试样例
样例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是两个整数列表,a和b中的元素可能重复,目标是找到这两个列表中的共同元素。
-
基本步骤:
- 遍历列表
a: 外层for循环遍历列表a中的每个元素。 - 遍历列表
b: 内层for循环遍历列表b中的每个元素,检查b中是否有与a中当前元素相同的元素。 - 找出公共元素: 如果
a中的某个元素和b中的元素相等,就将这个元素添加到result列表中。
- 遍历列表
-
倒序输出:
- 找到所有公共元素后,代码会创建一个新的列表
result2,并将result列表中的元素从后往前(倒序)添加到result2中。
- 找到所有公共元素后,代码会创建一个新的列表
-
返回结果:
- 返回倒序后的公共元素列表
result2。
- 返回倒序后的公共元素列表
代码实现细节
-
遍历操作:
for (int num1 : a):遍历a列表的每个元素。for (int num2 : b):遍历b列表的每个元素。if (num2 == num1):判断num1是否等于num2,即判断是否为公共元素。如果相等,说明这是一个公共元素,将其添加到result列表中。
-
倒序输出:
- 通过
for (int i = result.size() - 1; i >= 0; i--)遍历result列表,并将元素倒序地添加到result2中。
- 通过
具体步骤:
-
找公共元素:
- 外层循环遍历
a列表的每个元素,内层循环遍历b列表的每个元素,检查它们是否相等。 - 如果相等,则将该元素添加到
result列表。
- 外层循环遍历
-
倒序操作:
- 使用反向循环,将
result列表中的元素倒序添加到result2中。
- 使用反向循环,将
-
返回倒序后的结果:
- 返回倒序后的
result2列表。
- 返回倒序后的
代码优化建议
-
性能问题: 当前的代码在找公共元素时是用两个嵌套的
for循环遍历a和b列表,这样的时间复杂度是O(n * m),其中n是a列表的大小,m是b列表的大小。这个方法对于大型数据集可能效率较低。为了优化性能,可以使用哈希集合来存储
b列表的元素,这样可以将查找操作从O(m)优化为O(1),从而将整体复杂度降低到O(n + m)。
代码优化(使用 HashSet)
javaCopy Code
import java.util.*;
public class Main {
public static List<Integer> solution(List<Integer> a, List<Integer> b) {
Set<Integer> setB = new HashSet<>(b); // 将 b 列表转化为哈希集合
List<Integer> result = new ArrayList<>();
// 遍历 a 列表,检查每个元素是否在 setB 中
for (int num1 : a) {
if (setB.contains(num1)) {
result.add(num1);
}
}
// 倒排输出
List<Integer> result2 = new ArrayList<>();
for (int i = result.size() - 1; i >= 0; i--) {
result2.add(result.get(i));
}
return result2;
}
public static void main(String[] args) {
System.out.println(solution(Arrays.asList(1, 2, 3, 7), Arrays.asList(2, 5, 7)).equals(Arrays.asList(7, 2)));
System.out.println(solution(Arrays.asList(1, 4, 8, 10), Arrays.asList(2, 4, 8, 10)).equals(Arrays.asList(10, 8, 4)));
System.out.println(solution(Arrays.asList(3, 5, 9), Arrays.asList(1, 4, 6)).equals(Collections.emptyList()));
System.out.println(solution(Arrays.asList(1, 2, 3), Arrays.asList(1, 2, 3)).equals(Arrays.asList(3, 2, 1)));
}
}
测试用例
-
输入:
a = [1, 2, 3, 7],b = [2, 5, 7]
输出:[7, 2]- 共同元素是
2和7,倒序输出7, 2。
- 共同元素是
-
输入:
a = [1, 4, 8, 10],b = [2, 4, 8, 10]
输出:[10, 8, 4]- 共同元素是
4, 8, 10,倒序输出10, 8, 4。
- 共同元素是
-
输入:
a = [3, 5, 9],b = [1, 4, 6]
输出:[]- 没有共同元素,返回空列表。
-
输入:
a = [1, 2, 3],b = [1, 2, 3]
输出:[3, 2, 1]- 共同元素是
1, 2, 3,倒序输出3, 2, 1。
- 共同元素是
总结
- 这段代码通过嵌套循环查找公共元素,并通过倒序输出满足题目要求。
- 在性能方面,使用哈希集合避免了双重循环的低效操作。
心得:
使用MarsCode AI编写代码让我体验到了编程的便利与高效。AI能够快速生成代码示例,帮助我理解不同编程概念。通过交互式的反馈,我能迅速调整思路,解决问题。同时,MarsCode AI提供的建议让我了解到更多最佳实践,提升了我的编码水平。这种工具不仅节省了时间,还激发了我的创造力,尤其是在处理复杂问题时,AI的支持显得尤为重要。总的来说,MarsCode AI是编程学习和实践中的得力助手。