LeetCode 2956: Find Common Elements Between Two Arrays (Set Membership Counting)
LeetCode 2956Hash SetCountingToday we solve LeetCode 2956 - Find Common Elements Between Two Arrays.
Source: https://leetcode.com/problems/find-common-elements-between-two-arrays/
English
Problem Summary
Given two integer arrays nums1 and nums2, return [a, b] where:
- a is how many elements in nums1 appear in nums2.
- b is how many elements in nums2 appear in nums1.
Key Insight
We only need membership checks, not positions. So convert both arrays into sets: set1 and set2. Then scan each original array and count whether each value exists in the opposite set.
Algorithm
- Build set1 from nums1 and set2 from nums2.
- For each x in nums1, if x in set2, increment a.
- For each y in nums2, if y in set1, increment b.
- Return [a, b].
Complexity Analysis
Let n = len(nums1), m = len(nums2).
Time: O(n + m).
Space: O(n + m).
Common Pitfalls
- Mistakenly counting unique matches only. The problem counts by array positions, so duplicates in the scanned array should be counted repeatedly if membership is true.
- Using nested loops causes O(nm) and is unnecessary.
- Confusing intersection size with the required two directional counts.
Reference Implementations (Java / Go / C++ / Python / JavaScript)
class Solution {
public int[] findIntersectionValues(int[] nums1, int[] nums2) {
Set<Integer> set1 = new HashSet<>();
Set<Integer> set2 = new HashSet<>();
for (int x : nums1) set1.add(x);
for (int y : nums2) set2.add(y);
int a = 0, b = 0;
for (int x : nums1) {
if (set2.contains(x)) a++;
}
for (int y : nums2) {
if (set1.contains(y)) b++;
}
return new int[]{a, b};
}
}func findIntersectionValues(nums1 []int, nums2 []int) []int {
set1 := make(map[int]bool)
set2 := make(map[int]bool)
for _, x := range nums1 {
set1[x] = true
}
for _, y := range nums2 {
set2[y] = true
}
a, b := 0, 0
for _, x := range nums1 {
if set2[x] {
a++
}
}
for _, y := range nums2 {
if set1[y] {
b++
}
}
return []int{a, b}
}class Solution {
public:
vector<int> findIntersectionValues(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> set1(nums1.begin(), nums1.end());
unordered_set<int> set2(nums2.begin(), nums2.end());
int a = 0, b = 0;
for (int x : nums1) {
if (set2.count(x)) a++;
}
for (int y : nums2) {
if (set1.count(y)) b++;
}
return {a, b};
}
};class Solution:
def findIntersectionValues(self, nums1: List[int], nums2: List[int]) -> List[int]:
set1 = set(nums1)
set2 = set(nums2)
a = sum(1 for x in nums1 if x in set2)
b = sum(1 for y in nums2 if y in set1)
return [a, b]var findIntersectionValues = function(nums1, nums2) {
const set1 = new Set(nums1);
const set2 = new Set(nums2);
let a = 0, b = 0;
for (const x of nums1) {
if (set2.has(x)) a++;
}
for (const y of nums2) {
if (set1.has(y)) b++;
}
return [a, b];
};中文
题目概述
给定两个整数数组 nums1 和 nums2,返回 [a, b]:
- a 表示 nums1 里有多少元素出现在 nums2 中。
- b 表示 nums2 里有多少元素出现在 nums1 中。
核心思路
本题关键是“是否存在”判断,不关心位置,所以先把两个数组分别放进哈希集合:set1、set2。随后分别扫描原数组,在对方集合里做成员查询并计数。
算法步骤
- 用 nums1 构建 set1,用 nums2 构建 set2。
- 遍历 nums1:若 x in set2,a++。
- 遍历 nums2:若 y in set1,b++。
- 返回 [a, b]。
复杂度分析
设 n = len(nums1),m = len(nums2)。
时间复杂度:O(n + m)。
空间复杂度:O(n + m)。
常见陷阱
- 把题目误解成“只统计唯一值交集大小”。实际上这里按数组位置计数,若同一值在被扫描数组中重复出现且在对方集合里存在,就要重复计数。
- 使用双重循环会退化到 O(nm)。
- 把“两个方向的计数”误写成同一个值。
多语言参考实现(Java / Go / C++ / Python / JavaScript)
class Solution {
public int[] findIntersectionValues(int[] nums1, int[] nums2) {
Set<Integer> set1 = new HashSet<>();
Set<Integer> set2 = new HashSet<>();
for (int x : nums1) set1.add(x);
for (int y : nums2) set2.add(y);
int a = 0, b = 0;
for (int x : nums1) {
if (set2.contains(x)) a++;
}
for (int y : nums2) {
if (set1.contains(y)) b++;
}
return new int[]{a, b};
}
}func findIntersectionValues(nums1 []int, nums2 []int) []int {
set1 := make(map[int]bool)
set2 := make(map[int]bool)
for _, x := range nums1 {
set1[x] = true
}
for _, y := range nums2 {
set2[y] = true
}
a, b := 0, 0
for _, x := range nums1 {
if set2[x] {
a++
}
}
for _, y := range nums2 {
if set1[y] {
b++
}
}
return []int{a, b}
}class Solution {
public:
vector<int> findIntersectionValues(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> set1(nums1.begin(), nums1.end());
unordered_set<int> set2(nums2.begin(), nums2.end());
int a = 0, b = 0;
for (int x : nums1) {
if (set2.count(x)) a++;
}
for (int y : nums2) {
if (set1.count(y)) b++;
}
return {a, b};
}
};class Solution:
def findIntersectionValues(self, nums1: List[int], nums2: List[int]) -> List[int]:
set1 = set(nums1)
set2 = set(nums2)
a = sum(1 for x in nums1 if x in set2)
b = sum(1 for y in nums2 if y in set1)
return [a, b]var findIntersectionValues = function(nums1, nums2) {
const set1 = new Set(nums1);
const set2 = new Set(nums2);
let a = 0, b = 0;
for (const x of nums1) {
if (set2.has(x)) a++;
}
for (const y of nums2) {
if (set1.has(y)) b++;
}
return [a, b];
};
Comments