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

52 阅读3分钟

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

摘要

本文探讨了如何利用倒排索引实现高效的搜索引擎。给定两个按升序排列的帖子ID列表,本文将演示如何使用双指针法找到它们的交集,并按从大到小的顺序返回结果。我们提供了详细的步骤、算法分析及代码实现。

问题描述

小S帮助朋友们建立搜索引擎,用户可以通过倒排索引快速找到感兴趣的帖子。每个单词对应一个包含该单词的帖子ID的列表,ID按从小到大的顺序排列。若要找到同时包含两个单词的帖子ID,需要计算两个列表的交集,并按从大到小的顺序输出。

测试样例

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

  • 输入:a = [1, 4, 8, 10], b = [2, 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. 使用双指针法:因为两个列表都是按升序排列的,使用双指针可以高效地找到交集。时间复杂度为 O(n+m)O(n + m),其中 nnmm 是两个列表的长度。
  2. 遍历两个列表
    • 使用两个指针分别指向两个列表的当前元素。
    • 如果相等,则将该元素加入结果列表,并同时移动两个指针。
    • 如果一个指针指向的元素小于另一个,则移动较小的指针。

代码实现

Go语言代码

package main

import (
	"fmt"
)

func solution(a []int, b []int) (ans []int) {
	// 使用双指针法
	for i, j := len(a)-1, len(b)-1; i >= 0 && j >= 0; {
		if a[i] == b[j] {
			ans = append(ans, a[i]) // 添加交集元素
			i--
			j--
		} else {
			if a[i] > b[j] {
				i-- // 移动 a 的指针
			} else {
				j-- // 移动 b 的指针
			}
		}
	}
	return ans
}

func main() {
	fmt.Println(equal(solution([]int{1, 2, 3, 7}, []int{2, 5, 7}), []int{7, 2}))
	fmt.Println(equal(solution([]int{1, 4, 8, 10}, []int{2, 4, 8, 10}), []int{10, 8, 4}))
	fmt.Println(equal(solution([]int{3, 5, 9}, []int{1, 4, 6}), []int{}))
	fmt.Println(equal(solution([]int{1, 2, 3}, []int{1, 2, 3}), []int{3, 2, 1}))
}

func equal(a, b []int) bool {
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if a[i] != b[i] {
			return false
		}
	}
	return true
}

Python代码

def solution(a, b):
    """
    该函数接受两个整数列表 a 和 b,返回它们的公共元素(按逆序)。
    使用双指针法从两个列表的尾部向前遍历。
    """
    ans = []  # 初始化结果列表
    i, j = len(a) - 1, len(b) - 1  # 从两个列表的末尾开始

    while i >= 0 and j >= 0:  # 当两个指针均未越界
        if a[i] == b[j]:  # 如果元素相同
            ans.append(a[i])  # 将公共元素添加到结果中
            i -= 1  # 两个指针均向前移动
            j -= 1
        else:
            if a[i] > b[j]:  # 如果 a 的元素大于 b 的元素
                i -= 1  # 移动 a 的指针
            else:
                j -= 1  # 移动 b 的指针

    return ans  # 返回结果列表


def equal(a, b):
    """
    辅助函数,用于比较两个列表是否相等。
    """
    if len(a) != len(b):  # 如果长度不同,返回 False
        return False
    for i in range(len(a)):
        if a[i] != b[i]:  # 如果有任何元素不同,返回 False
            return False
    return True  # 如果所有元素都相同,返回 True


if __name__ == "__main__":
    # 添加测试用例
    print(equal(solution([1, 2, 3, 7], [2, 5, 7]), [7, 2]))  # 应输出 True
    print(equal(solution([1, 4, 8, 10], [2, 4, 8, 10]), [10, 8, 4]))  # 应输出 True
    print(equal(solution([3, 5, 9], [1, 4, 6]), []))  # 应输出 True
    print(equal(solution([1, 2, 3], [1, 2, 3]), [3, 2, 1]))  # 应输出 True