diff --git a/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/README.md b/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/README.md index 90d93a9f67e8f..8299293b49e8e 100644 --- a/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/README.md +++ b/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/README.md @@ -49,7 +49,7 @@ i = 2:1,2 和 3 是两个数组的前缀公共元素,所以 C[2] = 3 。 -**方法一:计数 + 枚举** +**方法一:计数** 我们可以使用两个数组 $cnt1$ 和 $cnt2$ 分别记录数组 $A$ 和 $B$ 中每个元素出现的次数,用数组 $ans$ 记录答案。 @@ -59,6 +59,18 @@ i = 2:1,2 和 3 是两个数组的前缀公共元素,所以 C[2] = 3 。 时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $A$ 和 $B$ 的长度。 +**方法二:位运算(异或运算)** + +我们可以使用一个长度为 $n+1$ 的数组 $vis$ 记录数组 $A$ 和 $B$ 中每个元素的出现情况,数组 $vis$ 的初始值为 $1$。另外,我们用一个变量 $s$ 记录当前公共元素的个数。 + +接下来,我们遍历数组 $A$ 和 $B$,更新 $vis[A[i]] = vis[A[i]] \oplus 1$,并且更新 $vis[B[i]] = vis[B[i]] \oplus 1$,其中 $\oplus$ 表示异或运算。 + +如果遍历到当前位置,元素 $A[i]$ 出现过两次(即在数组 $A$ 和 $B$ 中都出现过),那么 $vis[A[i]]$ 的值将为会 $1$,我们将 $s$ 加一。同理,如果元素 $B[i]$ 出现过两次,那么 $vis[B[i]]$ 的值将为会 $1$,我们将 $s$ 加一。然后将 $s$ 的值加入到答案数组 $ans$ 中。 + +遍历结束后,返回答案数组 $ans$ 即可。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $A$ 和 $B$ 的长度。 + ### **Python3** @@ -79,6 +91,21 @@ class Solution: return ans ``` +```python +class Solution: + def findThePrefixCommonArray(self, A: List[int], B: List[int]) -> List[int]: + ans = [] + vis = [1] * (len(A) + 1) + s = 0 + for a, b in zip(A, B): + vis[a] ^= 1 + s += vis[a] + vis[b] ^= 1 + s += vis[b] + ans.append(s) + return ans +``` + ### **Java** @@ -102,6 +129,26 @@ class Solution { } ``` +```java +class Solution { + public int[] findThePrefixCommonArray(int[] A, int[] B) { + int n = A.length; + int[] ans = new int[n]; + int[] vis = new int[n + 1]; + Arrays.fill(vis, 1); + int s = 0; + for (int i = 0; i < n; ++i) { + vis[A[i]] ^= 1; + s += vis[A[i]]; + vis[B[i]] ^= 1; + s += vis[B[i]]; + ans[i] = s; + } + return ans; + } +} +``` + ### **C++** ```cpp @@ -123,6 +170,26 @@ public: }; ``` +```cpp +class Solution { +public: + vector findThePrefixCommonArray(vector& A, vector& B) { + int n = A.size(); + vector ans; + vector vis(n + 1, 1); + int s = 0; + for (int i = 0; i < n; ++i) { + vis[A[i]] ^= 1; + s += vis[A[i]]; + vis[B[i]] ^= 1; + s += vis[B[i]]; + ans.push_back(s); + } + return ans; + } +}; +``` + ### **Go** ```go @@ -143,14 +210,33 @@ func findThePrefixCommonArray(A []int, B []int) []int { } ``` +```go +func findThePrefixCommonArray(A []int, B []int) (ans []int) { + vis := make([]int, len(A)+1) + for i := range vis { + vis[i] = 1 + } + s := 0 + for i, a := range A { + b := B[i] + vis[a] ^= 1 + s += vis[a] + vis[b] ^= 1 + s += vis[b] + ans = append(ans, s) + } + return +} +``` + ### **TypeScript** ```ts function findThePrefixCommonArray(A: number[], B: number[]): number[] { const n = A.length; - const cnt1: number[] = new Array(n + 1).fill(0); - const cnt2: number[] = new Array(n + 1).fill(0); - const ans: number[] = new Array(n).fill(0); + const cnt1: number[] = Array(n + 1).fill(0); + const cnt2: number[] = Array(n + 1).fill(0); + const ans: number[] = Array(n).fill(0); for (let i = 0; i < n; ++i) { ++cnt1[A[i]]; ++cnt2[B[i]]; @@ -162,6 +248,24 @@ function findThePrefixCommonArray(A: number[], B: number[]): number[] { } ``` +```ts +function findThePrefixCommonArray(A: number[], B: number[]): number[] { + const n = A.length; + const vis: number[] = Array(n + 1).fill(1); + const ans: number[] = []; + let s = 0; + for (let i = 0; i < n; ++i) { + const [a, b] = [A[i], B[i]]; + vis[a] ^= 1; + s += vis[a]; + vis[b] ^= 1; + s += vis[b]; + ans.push(s); + } + return ans; +} +``` + ### **...** ``` diff --git a/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/README_EN.md b/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/README_EN.md index ac41f81903de2..47905134695fd 100644 --- a/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/README_EN.md +++ b/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/README_EN.md @@ -45,15 +45,27 @@ At i = 2: 1, 2, and 3 are common in A and B, so C[2] = 3. ## Solutions -**Solution 1: Count + Enumeration** +**Solution 1: Counting** -We can use two arrays $cnt1$ and $cnt2$ to record the number of occurrences of each element in arrays $A$ and $B$, and use array $ans$ to record the answer. +We can use two arrays $cnt1$ and $cnt2$ to record the occurrence times of each element in arrays $A$ and $B$ respectively, and use an array $ans$ to record the answer. -Traverse arrays $A$ and $B$, add the number of occurrences of $A[i]$ in $cnt1$ by one, and add the number of occurrences of $B[i]$ in $cnt2$ by one. Then enumerate $j \in [1,n]$, calculate the minimum value of the number of occurrences of each element $j$ in $cnt1$ and $cnt2$, and add it to $ans[i]$. +Traverse arrays $A$ and $B$, increment the occurrence times of $A[i]$ in $cnt1$, and increment the occurrence times of $B[i]$ in $cnt2$. Then enumerate $j \in [1,n]$, calculate the minimum occurrence times of each element $j$ in $cnt1$ and $cnt2$, and accumulate them into $ans[i]$. -After the traversal is over, return the answer array $ans$. +After the traversal, return the answer array $ans$. -The time complexity is $O(n^2)$, and the space complexity is $O(n)$. Where $n$ is the length of arrays $A$ and $B$. +The time complexity is $O(n^2)$, and the space complexity is $O(n)$. Here, $n$ is the length of arrays $A$ and $B$. + +**Solution 2: Bit Operation (XOR Operation)** + +We can use an array $vis$ of length $n+1$ to record the occurrence situation of each element in arrays $A$ and $B$, the initial value of array $vis$ is $1$. In addition, we use a variable $s$ to record the current number of common elements. + +Next, we traverse arrays $A$ and $B$, update $vis[A[i]] = vis[A[i]] \oplus 1$, and update $vis[B[i]] = vis[B[i]] \oplus 1$, where $\oplus$ represents XOR operation. + +If at the current position, the element $A[i]$ has appeared twice (i.e., it has appeared in both arrays $A$ and $B$), then the value of $vis[A[i]]$ will be $1$, and we increment $s$. Similarly, if the element $B[i]$ has appeared twice, then the value of $vis[B[i]]$ will be $1$, and we increment $s$. Then add the value of $s$ to the answer array $ans$. + +After the traversal, return the answer array $ans$. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of arrays $A$ and $B$. @@ -73,6 +85,21 @@ class Solution: return ans ``` +```python +class Solution: + def findThePrefixCommonArray(self, A: List[int], B: List[int]) -> List[int]: + ans = [] + vis = [1] * (len(A) + 1) + s = 0 + for a, b in zip(A, B): + vis[a] ^= 1 + s += vis[a] + vis[b] ^= 1 + s += vis[b] + ans.append(s) + return ans +``` + ### **Java** ```java @@ -94,6 +121,26 @@ class Solution { } ``` +```java +class Solution { + public int[] findThePrefixCommonArray(int[] A, int[] B) { + int n = A.length; + int[] ans = new int[n]; + int[] vis = new int[n + 1]; + Arrays.fill(vis, 1); + int s = 0; + for (int i = 0; i < n; ++i) { + vis[A[i]] ^= 1; + s += vis[A[i]]; + vis[B[i]] ^= 1; + s += vis[B[i]]; + ans[i] = s; + } + return ans; + } +} +``` + ### **C++** ```cpp @@ -115,6 +162,26 @@ public: }; ``` +```cpp +class Solution { +public: + vector findThePrefixCommonArray(vector& A, vector& B) { + int n = A.size(); + vector ans; + vector vis(n + 1, 1); + int s = 0; + for (int i = 0; i < n; ++i) { + vis[A[i]] ^= 1; + s += vis[A[i]]; + vis[B[i]] ^= 1; + s += vis[B[i]]; + ans.push_back(s); + } + return ans; + } +}; +``` + ### **Go** ```go @@ -135,14 +202,33 @@ func findThePrefixCommonArray(A []int, B []int) []int { } ``` +```go +func findThePrefixCommonArray(A []int, B []int) (ans []int) { + vis := make([]int, len(A)+1) + for i := range vis { + vis[i] = 1 + } + s := 0 + for i, a := range A { + b := B[i] + vis[a] ^= 1 + s += vis[a] + vis[b] ^= 1 + s += vis[b] + ans = append(ans, s) + } + return +} +``` + ### **TypeScript** ```ts function findThePrefixCommonArray(A: number[], B: number[]): number[] { const n = A.length; - const cnt1: number[] = new Array(n + 1).fill(0); - const cnt2: number[] = new Array(n + 1).fill(0); - const ans: number[] = new Array(n).fill(0); + const cnt1: number[] = Array(n + 1).fill(0); + const cnt2: number[] = Array(n + 1).fill(0); + const ans: number[] = Array(n).fill(0); for (let i = 0; i < n; ++i) { ++cnt1[A[i]]; ++cnt2[B[i]]; @@ -154,6 +240,24 @@ function findThePrefixCommonArray(A: number[], B: number[]): number[] { } ``` +```ts +function findThePrefixCommonArray(A: number[], B: number[]): number[] { + const n = A.length; + const vis: number[] = Array(n + 1).fill(1); + const ans: number[] = []; + let s = 0; + for (let i = 0; i < n; ++i) { + const [a, b] = [A[i], B[i]]; + vis[a] ^= 1; + s += vis[a]; + vis[b] ^= 1; + s += vis[b]; + ans.push(s); + } + return ans; +} +``` + ### **...** ``` diff --git a/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.cpp b/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.cpp index 5f8385ad9dc64..20edbdd260cbc 100644 --- a/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.cpp +++ b/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.cpp @@ -1,16 +1,17 @@ -class Solution { -public: - vector findThePrefixCommonArray(vector& A, vector& B) { - int n = A.size(); - vector ans(n); - vector cnt1(n + 1), cnt2(n + 1); - for (int i = 0; i < n; ++i) { - ++cnt1[A[i]]; - ++cnt2[B[i]]; - for (int j = 1; j <= n; ++j) { - ans[i] += min(cnt1[j], cnt2[j]); - } - } - return ans; - } +class Solution { +public: + vector findThePrefixCommonArray(vector& A, vector& B) { + int n = A.size(); + vector ans; + vector vis(n + 1, 1); + int s = 0; + for (int i = 0; i < n; ++i) { + vis[A[i]] ^= 1; + s += vis[A[i]]; + vis[B[i]] ^= 1; + s += vis[B[i]]; + ans.push_back(s); + } + return ans; + } }; \ No newline at end of file diff --git a/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.go b/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.go index 5544f00f57aaf..255d1c1ecc287 100644 --- a/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.go +++ b/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.go @@ -1,15 +1,16 @@ -func findThePrefixCommonArray(A []int, B []int) []int { - n := len(A) - cnt1 := make([]int, n+1) - cnt2 := make([]int, n+1) - ans := make([]int, n) +func findThePrefixCommonArray(A []int, B []int) (ans []int) { + vis := make([]int, len(A)+1) + for i := range vis { + vis[i] = 1 + } + s := 0 for i, a := range A { b := B[i] - cnt1[a]++ - cnt2[b]++ - for j := 1; j <= n; j++ { - ans[i] += min(cnt1[j], cnt2[j]) - } + vis[a] ^= 1 + s += vis[a] + vis[b] ^= 1 + s += vis[b] + ans = append(ans, s) } - return ans + return } \ No newline at end of file diff --git a/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.java b/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.java index c60fe315c0a57..8bcfc980a427a 100644 --- a/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.java +++ b/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.java @@ -1,16 +1,17 @@ -class Solution { - public int[] findThePrefixCommonArray(int[] A, int[] B) { - int n = A.length; - int[] ans = new int[n]; - int[] cnt1 = new int[n + 1]; - int[] cnt2 = new int[n + 1]; - for (int i = 0; i < n; ++i) { - ++cnt1[A[i]]; - ++cnt2[B[i]]; - for (int j = 1; j <= n; ++j) { - ans[i] += Math.min(cnt1[j], cnt2[j]); - } - } - return ans; - } +class Solution { + public int[] findThePrefixCommonArray(int[] A, int[] B) { + int n = A.length; + int[] ans = new int[n]; + int[] vis = new int[n + 1]; + Arrays.fill(vis, 1); + int s = 0; + for (int i = 0; i < n; ++i) { + vis[A[i]] ^= 1; + s += vis[A[i]]; + vis[B[i]] ^= 1; + s += vis[B[i]]; + ans[i] = s; + } + return ans; + } } \ No newline at end of file diff --git a/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.py b/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.py index e9de69108a5b9..1c2a57f984d33 100644 --- a/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.py +++ b/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.py @@ -1,11 +1,12 @@ -class Solution: - def findThePrefixCommonArray(self, A: List[int], B: List[int]) -> List[int]: - ans = [] - cnt1 = Counter() - cnt2 = Counter() - for a, b in zip(A, B): - cnt1[a] += 1 - cnt2[b] += 1 - t = sum(min(v, cnt2[x]) for x, v in cnt1.items()) - ans.append(t) - return ans +class Solution: + def findThePrefixCommonArray(self, A: List[int], B: List[int]) -> List[int]: + ans = [] + vis = [1] * (len(A) + 1) + s = 0 + for a, b in zip(A, B): + vis[a] ^= 1 + s += vis[a] + vis[b] ^= 1 + s += vis[b] + ans.append(s) + return ans diff --git a/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.ts b/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.ts index 4205681668982..7dc8c3472790a 100644 --- a/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.ts +++ b/solution/2600-2699/2657.Find the Prefix Common Array of Two Arrays/Solution.ts @@ -1,14 +1,15 @@ function findThePrefixCommonArray(A: number[], B: number[]): number[] { const n = A.length; - const cnt1: number[] = new Array(n + 1).fill(0); - const cnt2: number[] = new Array(n + 1).fill(0); - const ans: number[] = new Array(n).fill(0); + const vis: number[] = Array(n + 1).fill(1); + const ans: number[] = []; + let s = 0; for (let i = 0; i < n; ++i) { - ++cnt1[A[i]]; - ++cnt2[B[i]]; - for (let j = 1; j <= n; ++j) { - ans[i] += Math.min(cnt1[j], cnt2[j]); - } + const [a, b] = [A[i], B[i]]; + vis[a] ^= 1; + s += vis[a]; + vis[b] ^= 1; + s += vis[b]; + ans.push(s); } return ans; }