小S的倒排索引 | 豆包MarsCode AI刷题

做题笔记:求两个倒排链的交集

问题分析

本题要求计算两个倒排链(列表)ab 的交集,并返回交集的结果按照从大到小的顺序排列。倒排索引常用于搜索引擎中,每个单词都关联一个帖子ID的列表,而交集操作通常是为了找到同时包含两个词的帖子。

关键要求

  • 找出两个倒排链中共同出现的帖子ID。
  • 返回结果按从大到小的顺序排列。

解题思路

  1. 交集求解 :给定两个已排序的列表(倒排链),我们需要找出它们的交集。可以利用双指针法来高效地求解交集。因为两个列表都是升序排列的,我们从两个列表的末尾开始比较元素,如果它们相等,则将该元素添加到结果列表中。如果不相等,则移动指针指向较大的元素。
  2. 排序:由于题目要求返回的结果是按从大到小的顺序排列,我们可以在求交集的过程中就将结果添加到一个列表中,然后返回时可以直接得到正确的顺序。由于我们是从两个列表的末尾往前遍历,因此得到的交集本身是从大到小排列的。
  3. 时间复杂度 :由于两个列表都是有序的,双指针法的时间复杂度是 O(n + m),其中 nm 分别是两个列表的长度。此方法相比直接进行集合运算要更加高效。

代码实现

csharp 复制代码
import java.util.ArrayList;
import java.util.List;

public class Solution {
    public static List<Integer> solution(List<Integer> a, List<Integer> b) {
        // 初始化结果列表
        List<Integer> result = new ArrayList<>();
        // 双指针遍历两个列表
        int i = a.size() - 1; // 指向列表a的末尾
        int j = b.size() - 1; // 指向列表b的末尾
        
        while (i >= 0 && j >= 0) {
            if (a.get(i).equals(b.get(j))) {
                // 如果两个指针指向的元素相同,加入结果列表
                result.add(a.get(i));
                i--;
                j--;
            } else if (a.get(i) > b.get(j)) {
                // a的当前元素较大,移动指针i
                i--;
            } else {
                // b的当前元素较大,移动指针j
                j--;
            }
        }
        return result; // 返回结果列表
    }
}

代码解析

  1. 双指针初始化 :我们初始化两个指针 ij,分别指向列表 ab 的最后一个元素。因为我们要从后往前比较,以便得到按从大到小排序的结果。

  2. 遍历过程

    • 如果 a.get(i)b.get(j) 相等,说明这两个帖子ID是共同的,将其添加到结果列表中,然后分别移动指针 ij
    • 如果 a.get(i) 大于 b.get(j),则说明列表 a 中的当前元素较大,因此应该将 i 向前移动,检查 a 中下一个元素。
    • 如果 b.get(j) 大于 a.get(i),则说明列表 b 中的当前元素较大,应该将 j 向前移动,检查 b 中下一个元素。
  3. 返回结果 :最终的结果列表 result 中包含的是交集元素,且按从大到小的顺序排列。

时间复杂度分析

  • 时间复杂度 :由于我们通过双指针法遍历两个列表,且每个元素最多被访问一次,因此时间复杂度为 O(n + m),其中 nm 分别是两个列表的长度。
  • 空间复杂度 :由于我们只需要一个额外的结果列表来存储交集元素,空间复杂度是 O(min(n, m)),即结果列表的大小。

测试用例分析

考虑几个测试样例来验证代码的正确性。

样例1: 输入:

css 复制代码
a = [1, 2, 3, 7], b = [2, 5, 7]

输出:

csharp 复制代码
[7, 2]
  • 交集为 27,按从大到小的顺序排列为 [7, 2]

样例2: 输入:

css 复制代码
a = [1, 4, 8, 10], b = [2, 4, 8, 10]

输出:

csharp 复制代码
[10, 8, 4]
  • 交集为 4, 8, 10,按从大到小的顺序排列为 [10, 8, 4]

样例3: 输入:

css 复制代码
a = [3, 5, 9], b = [1, 4, 6]

输出:

css 复制代码
[]
  • 无交集,输出空列表 []

样例4: 输入:

css 复制代码
a = [1, 2, 3], b = [1, 2, 3]

输出:

csharp 复制代码
[3, 2, 1]
  • 交集为 1, 2, 3,按从大到小的顺序排列为 [3, 2, 1]
相关推荐
用户826014428301 天前
469. 环形数组最大子数组和问题
青训营笔记
用户605721920982 天前
奇妙货币交易问题 | 豆包MarsCode AI刷题
青训营笔记
我明天再来学Web渗透3 天前
“抖音互联网架构分析及高可用系统构建思考”(方向三)| 豆包MarsCode AI刷题
青训营笔记
用户302133066204 天前
第三次刷题 | 豆包MarsCode AI刷题
青训营笔记
用户9105973027709 天前
CSS详解| 豆包MarsCode AI刷题
青训营笔记
huyck9 天前
伴学笔记1|豆包MarsCode AI 刷题
青训营笔记
用户197009008153814 天前
实现一个TodoList | 青训营 x 豆包MarsCode技术训练营
青训营笔记
幻614 天前
小U的相似字符串 | 豆包MarsCode AI刷题
青训营笔记
Grin1 个月前
寻找最大葫芦 | 豆包MarsCode AI刷题
青训营笔记