LeetCode 2657. 找到两个数组的前缀公共数组【集合,位运算】中等

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章中,我不仅会讲解多种解题思路及其优化,还会用多种编程语言实现题解,涉及到通用解法时更将归纳总结出相应的算法模板。

为了方便在PC上运行调试、分享代码文件,我还建立了相关的仓库:https://github.com/memcpy0/LeetCode-Conquest。在这一仓库中,你不仅可以看到LeetCode原题链接、题解代码、题解文章链接、同类题目归纳、通用解法总结等,还可以看到原题出现频率和相关企业等重要信息。如果有其他优选题解,还可以一同分享给他人。

由于本系列文章的内容随时可能发生更新变动,欢迎关注和收藏征服LeetCode系列文章目录一文以作备忘。

给你两个下标从 0 开始长度为 n 的整数排列 AB

AB前缀公共数组 定义为数组 C ,其中 C[i] 是数组 AB 到下标为 i 之前公共元素的数目。

请你返回 AB前缀公共数组

如果一个长度为 n 的数组包含 1n 的元素恰好一次,我们称这个数组是一个长度为 n排列

示例 1:

java 复制代码
输入:A = [1,3,2,4], B = [3,1,2,4]
输出:[0,2,3,4]
解释:i = 0:没有公共元素,所以 C[0] = 0 。
i = 1:1 和 3 是两个数组的前缀公共元素,所以 C[1] = 2 。
i = 2:1,2 和 3 是两个数组的前缀公共元素,所以 C[2] = 3 。
i = 3:1,2,3 和 4 是两个数组的前缀公共元素,所以 C[3] = 4 。

示例 2:

java 复制代码
输入:A = [2,3,1], B = [3,1,2]
输出:[0,1,3]
解释:i = 0:没有公共元素,所以 C[0] = 0 。
i = 1:只有 3 是公共元素,所以 C[1] = 1 。
i = 2:1,2 和 3 是两个数组的前缀公共元素,所以 C[2] = 3 。

提示:

  • 1 <= A.length == B.length == n <= 50
  • 1 <= A[i], B[i] <= n
  • 题目保证 AB 两个数组都是 n 个元素的排列。

方法 位运算加速求交集

用二进制数表示集合,两个二进制数的 AND 就是集合的交集,二进制数中 1 的个数就是交集的大小。

java 复制代码
class Solution {
    public int[] findThePrefixCommonArray(int[] a, int[] b) {
        long p = 0, q = 0;
        for (int i = 0; i < a.length; i++) {
            p |= 1L << a[i];
            q |= 1L << b[i];
            a[i] = Long.bitCount(p & q);
        }
        return a;
    }
}
cpp 复制代码
class Solution {
public:
    vector<int> findThePrefixCommonArray(vector<int>& a, vector<int>& b) {
        uint64_t p = 0, q = 0;
        for (int i = 0; i < a.size(); i++) {
            p |= 1ULL << a[i];
            q |= 1ULL << b[i];
            a[i] = popcount(p & q);
        }
        return a;
    }
};
python 复制代码
class Solution:
    def findThePrefixCommonArray(self, a: List[int], b: List[int]) -> List[int]:
        ans = []
        p = q = 0
        for x, y in zip(a, b):
            p |= 1 << x
            q |= 1 << y
            ans.append((p & q).bit_count())
        return ans
go 复制代码
func findThePrefixCommonArray(a, b []int) []int {
	var p, q uint
	for i, x := range a {
		p |= 1 << x
		q |= 1 << b[i]
		a[i] = bits.OnesCount(p & q)
	}
	return a
}

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n) ,其中 n n n 是 n u m s nums nums 的长度。
  • 空间复杂度: O ( 1 ) O(1) O(1) 。返回值不计入。
相关推荐
AI备案指南-满满20 小时前
人工智能拟人化互动服务安全自评估报告的评估要点有哪些?
人工智能·算法·安全·机器人·大模型备案·算法备案
土司大王21 小时前
LeetCode hot100——两两交换链表中的节点
算法·leetcode·职场和发展
大熊背1 天前
树莓派IspPipeline LSC模块原理详解
算法·lsc·isppipeline·mesh lsc
测试19981 天前
Selenium 无法定位元素的几种解决方案
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例
zander2581 天前
LeetCode 300. 最长递增子序列
算法·leetcode·深度优先
欧叶冲冲冲1 天前
Python常见数据结构的CRUD(LeetCode高频版速查)
数据结构·python·leetcode
祖力551 天前
Linux应用软件编程:目录IO与framebuffer
linux·运维·算法·framebuffer·目录io
名字还没想好☜1 天前
Go 用 slices/maps 标准库泛型函数:告别手写 Contains、Sort、去重(Go 1.21)
开发语言·后端·算法·golang·go
地平线开发者1 天前
【模型轻量化专题】深度学习模型为什么需要轻量化
算法