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

61 阅读5分钟

题目解析:小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]

  1. 输入:

    • a 和 b 是两个整数列表,a 和 b 中的元素可能重复,目标是找到这两个列表中的共同元素。
  2. 基本步骤:

    • 遍历列表 a  外层 for 循环遍历列表 a 中的每个元素。
    • 遍历列表 b  内层 for 循环遍历列表 b 中的每个元素,检查 b 中是否有与 a 中当前元素相同的元素。
    • 找出公共元素:  如果 a 中的某个元素和 b 中的元素相等,就将这个元素添加到 result 列表中。
  3. 倒序输出:

    • 找到所有公共元素后,代码会创建一个新的列表 result2,并将 result 列表中的元素从后往前(倒序)添加到 result2 中。
  4. 返回结果:

    • 返回倒序后的公共元素列表 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 中。

具体步骤:

  1. 找公共元素:

    • 外层循环遍历 a 列表的每个元素,内层循环遍历 b 列表的每个元素,检查它们是否相等。
    • 如果相等,则将该元素添加到 result 列表。
  2. 倒序操作:

    • 使用反向循环,将 result 列表中的元素倒序添加到 result2 中。
  3. 返回倒序后的结果:

    • 返回倒序后的 result2 列表。

代码优化建议

  • 性能问题: 当前的代码在找公共元素时是用两个嵌套的 for 循环遍历 ab 列表,这样的时间复杂度是 O(n * m),其中 na 列表的大小,mb 列表的大小。这个方法对于大型数据集可能效率较低。

    为了优化性能,可以使用哈希集合来存储 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)));
    }
}

测试用例

  1. 输入:a = [1, 2, 3, 7], b = [2, 5, 7]
    输出:[7, 2]

    • 共同元素是 2 和 7,倒序输出 7, 2
  2. 输入:a = [1, 4, 8, 10], b = [2, 4, 8, 10]
    输出:[10, 8, 4]

    • 共同元素是 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]

    • 共同元素是 1, 2, 3,倒序输出 3, 2, 1

总结

  • 这段代码通过嵌套循环查找公共元素,并通过倒序输出满足题目要求。
  • 在性能方面,使用哈希集合避免了双重循环的低效操作。

心得:

使用MarsCode AI编写代码让我体验到了编程的便利与高效。AI能够快速生成代码示例,帮助我理解不同编程概念。通过交互式的反馈,我能迅速调整思路,解决问题。同时,MarsCode AI提供的建议让我了解到更多最佳实践,提升了我的编码水平。这种工具不仅节省了时间,还激发了我的创造力,尤其是在处理复杂问题时,AI的支持显得尤为重要。总的来说,MarsCode AI是编程学习和实践中的得力助手。