找到两个数组的前缀公共数组
难度:
标签:
题目描述
You are given two 0-indexed integer permutations A
and B
of length n
.
A prefix common array of A
and B
is an array C
such that C[i]
is equal to the count of numbers that are present at or before the index i
in both A
and B
.
Return the prefix common array of A
and B
.
A sequence of n
integers is called a permutation if it contains all integers from 1
to n
exactly once.
Example 1:
Input: A = [1,3,2,4], B = [3,1,2,4] Output: [0,2,3,4] Explanation: At i = 0: no number is common, so C[0] = 0. At i = 1: 1 and 3 are common in A and B, so C[1] = 2. At i = 2: 1, 2, and 3 are common in A and B, so C[2] = 3. At i = 3: 1, 2, 3, and 4 are common in A and B, so C[3] = 4.
Example 2:
Input: A = [2,3,1], B = [3,1,2] Output: [0,1,3] Explanation: At i = 0: no number is common, so C[0] = 0. At i = 1: only 3 is common in A and B, so C[1] = 1. At i = 2: 1, 2, and 3 are common in A and B, so C[2] = 3.
Constraints:
1 <= A.length == B.length == n <= 50
1 <= A[i], B[i] <= n
It is guaranteed that A and B are both a permutation of n integers.
代码结果
运行时间: 33 ms, 内存: 16.0 MB
/*
题目思路:
1. 创建一个长度为 n 的结果数组 C。
2. 使用两个集合来跟踪 A 和 B 的前缀元素。
3. 遍历数组,比较当前索引之前的前缀元素,统计公共元素的数量并存储到 C 中。
*/
import java.util.*;
import java.util.stream.*;
public class Solution {
public int[] findPrefixCommonArray(int[] A, int[] B) {
int n = A.length;
int[] C = new int[n];
Set<Integer> setA = new HashSet<>();
Set<Integer> setB = new HashSet<>();
IntStream.range(0, n).forEach(i -> {
setA.add(A[i]);
setB.add(B[i]);
C[i] = (int) setA.stream().filter(setB::contains).count();
});
return C;
}
}
解释
方法:
题解的核心思路在于利用两个集合来跟踪数组A和B中已经见过的元素。对于每个索引i,我们检查数组A和B的当前元素是否已经在对方的集合中出现过。如果是,相应的计数器(count_A或count_B)增加。这两个计数器分别跟踪A的元素在B的前缀中出现的次数和B的元素在A的前缀中出现的次数。最后,将这两个计数器的和存储在结果数组的相应位置。这种方法确保了即便元素以不同的顺序出现,也能正确计算出前缀中共有元素的数量。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在实现中,为什么要分别使用两个计数器count_A和count_B来跟踪交叉出现的元素,而不是单一计数器?
▷🦆
如果数组A和B的长度不同或不是完全的排列(即含有重复元素或不包含1到n的所有整数),该算法是否仍然有效?
▷🦆
算法中的逻辑对于元素的出现顺序是否敏感?即如果两个数组元素相同但顺序完全相反,输出结果会有何不同?
▷🦆
在题解中提到的集合seen_A和seen_B,当元素被添加进集合时,是否需要检查该元素之前是否已存在于集合中?
▷