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

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

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

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

给你两个下标从 0 开始长度为 n 的整数排列 A 和 B 。

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

请你返回 A 和 B 的 前缀公共数组 。

如果一个长度为 n 的数组包含 1 到 n 的元素恰好一次,我们称这个数组是一个长度为 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
  • 题目保证 A 和 B 两个数组都是 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) 。返回值不计入。
相关推荐
晒太羊的猫20 分钟前
hot100动态规划刷题
算法·动态规划
weixin_5310946943 分钟前
heap_4内存管理
java·开发语言·算法
余额瞒着我当琳1 小时前
红黑树的实现--红黑树的概念、规则、效率、结构、旋转、查找、验证
数据结构·c++·算法
程序员南飞1 小时前
win系统安装minio
java·数据结构·算法
青少儿编程课堂1 小时前
AC自动机多模式串匹配精讲:校园关键词巡检实战解析
c++·python·算法·bfs·信息学竞赛
我命由我123451 小时前
Photoshop - Photoshop 矢量蒙版
学习·职场和发展·产品运营·求职招聘·职场发展·产品经理·photoshop
longlongzihan2 小时前
LeetCode 5. 最长回文子串:从暴力匹配到中心扩展的思维演进
c++·算法·leetcode
waoooqwe2 小时前
问卷样本真实吗
大数据·数据库·算法·数据分析
苦瓜打怪兽2 小时前
leetcode 热题100(11. 盛最多水的容器)
python·算法·leetcode
w_zero_one3 小时前
链表(4)
java·数据结构·算法