Skip to content

Latest commit

 

History

History
178 lines (138 loc) · 5.04 KB

File metadata and controls

178 lines (138 loc) · 5.04 KB

English Version

题目描述

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

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

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

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

 

示例 1:

输入: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:

输入: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 个元素的排列。

解法

方法一:计数 + 枚举

我们可以使用两个数组 $cnt1$$cnt2$ 分别记录数组 $A$$B$ 中每个元素出现的次数,用数组 $ans$ 记录答案。

遍历数组 $A$$B$,将 $A[i]$$cnt1$ 中出现次数加一,将 $B[i]$$cnt2$ 中出现次数加一。然后枚举 $j \in [1,n]$,计算 $cnt1$$cnt2$ 中每个元素 $j$ 出现次数的最小值,累加到 $ans[i]$ 中。

遍历结束后,返回答案数组 $ans$ 即可。

时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $A$$B$ 的长度。

Python3

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

Java

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;
    }
}

C++

class Solution {
public:
    vector<int> findThePrefixCommonArray(vector<int>& A, vector<int>& B) {
        int n = A.size();
        vector<int> ans(n);
        vector<int> 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;
    }
};

Go

func findThePrefixCommonArray(A []int, B []int) []int {
	n := len(A)
	cnt1 := make([]int, n+1)
	cnt2 := make([]int, n+1)
	ans := make([]int, n)
	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])
		}
	}
	return ans
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

TypeScript

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);
    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]);
        }
    }
    return ans;
}

...