《关于倒排索引交集计算代码的学习总结与方法分享》| 豆包MarsCode AI刷题

63 阅读4分钟

一、题目解析 本题旨在解决根据两个倒排索引链(以列表形式表示,其中元素为帖子 ID),找出同时包含两个单词的帖子 ID,并按照从大到小顺序输出的问题。 ### 思路分析 - 首先,采用双指针法来遍历两个倒排索引列表 ab。初始化两个指针 ij 分别指向列表 ab 的开头。 - 在遍历过程中,比较当前指针所指的元素 a.get(i)b.get(j): - 如果两者相等,说明找到了一个同时在两个倒排链中的帖子 ID,将其添加到交集集合 intersection 中,然后同时移动两个指针 i++j++。 - 如果 a.get(i) 小于 b.get(j),意味着当前 a 列表中的元素较小,不太可能在后续的 b 列表中找到匹配,所以移动 a 列表的指针 i++,继续寻找可能的匹配。 - 反之,如果 a.get(i) 大于 b.get(j),则移动 b 列表的指针 j++。 - 当遍历完两个列表后,交集集合 intersection 中就包含了所有同时在两个倒排链中的帖子 ID。最后将交集集合转换为列表 result,并使用 Collections.reverseOrder() 进行降序排序,得到最终结果。 ### 代码详解 - Set<Integer> intersection = new HashSet<>();:创建一个 HashSet 用于存储交集元素,HashSet 可以自动去重,确保交集中不会有重复的帖子 ID。 - int i = 0, j = 0;:初始化双指针,分别指向两个倒排索引列表的起始位置。 - while (i < a.size() && j < b.size()) {...}:外层循环,只要两个指针都没有超出各自列表的范围,就继续进行比较。 - if (a.get(i).equals(b.get(j))) {...}:判断当前指针所指元素是否相等,相等则处理交集添加和指针移动。 - else if (a.get(i) < b.get(j)) {...}else {...}:根据元素大小关系移动相应指针。 - List<Integer> result = new ArrayList<>(intersection);:将交集集合转换为 ArrayList,方便后续排序操作。 - result.sort(Collections.reverseOrder());:使用 Collections 工具类的 reverseOrder() 方法对结果列表进行降序排序,该方法返回一个比较器,用于实现降序比较。 ## 二、知识总结 ### 新知识点 - 双指针法:在处理两个有序序列(本题中的倒排索引列表)的交集等问题时非常有效。通过同时移动两个指针,可以高效地比较元素并找出满足条件的公共元素,时间复杂度可以控制在 O(m+n)O(m + n),其中 mn 分别是两个列表的长度。 - 集合操作:使用 HashSet 来存储交集元素,利用了其去重特性。同时了解了 ArrayListHashSet 之间的转换,以及 Collections 工具类中排序方法的使用,如 reverseOrder() 实现降序排序。 ### 学习建议 - 对于双指针法,要多做一些相关练习题,如合并两个有序数组、寻找两个有序数组的中位数等题目,深入理解指针移动的逻辑和条件判断。可以通过手动模拟指针移动过程,在纸上画出数组和指针的变化情况,加深理解。 - 对于集合类的学习,要熟悉 HashSetArrayList 等常用集合的特点、方法和适用场景。可以阅读官方文档,了解其内部实现原理,例如 HashSet 基于哈希表实现去重机制。同时,多进行集合操作的代码练习,如集合的添加、删除、遍历、转换等操作,提高对集合的运用能力。 ## 三、学习计划 ### 刷题计划 - 按照数据结构和算法的知识点分类制定刷题计划。例如,先集中攻克数组相关题目,包括一维数组、二维数组的各种操作和应用,像本题所属的数组交集计算类题目。在掌握数组后,再学习链表、栈、队列等数据结构的题目。 - 每个知识点可以分为基础、中等、困难三个难度级别进行刷题。先从基础题目入手,理解基本概念和算法思想,然后逐步挑战中等和困难题目,提升解题能力。例如,对于双指针法,可以先做简单的双指针遍历数组求和的题目,再做像本题这样稍微复杂的双指针处理两个有序序列交集的题目,最后尝试解决涉及多个指针或与其他数据结构结合的高难度双指针题目。 ### 错题学习 - 建立错题本,将做错的题目整理到错题本中,记录错误原因、正确解法以及涉及的知识点。对于本题,如果错误可能是双指针移动逻辑错误或者集合操作不当,要详细记录下来。 - 定期回顾错题本,重新做错题,分析自己是否真正理解了错误原因并掌握了正确解法。可以将错题按照知识点分类回顾,比如每周抽出一定时间专门回顾数组相关错题,强化对该知识点的掌握。同时,对于多次做错的题目,要深入研究,寻找更多类似题目进行练习,直到彻底掌握。