トピック
元の質問
へのリンク正の整数配列Aが与えられた場合、Aのサブ配列内の異なる整数の数がたまたまKである場合、Aのこの連続的で、必ずしも独立していないサブ配列は、適切なサブ配列と呼ばれます。
(たとえば、[1,2,3,1,2]には1、2、および3の3つの異なる整数があります。)
Aの適切なサブ配列の数を返します。
例1:
入力:A = [1,2,1,2,3]、K = 2
出力:7
説明:正確に2つの異なる整数で構成されるサブ配列:[1,2]、[2,1]、[1、 2]、[2,3]、[1,2,1]、[2,1,2]、[1,2,1,2]。
例2:
入力:A = [1,2,1,3,4]、K = 3
出力:3
説明:正確に3つの異なる整数で構成されるサブ配列:[1,2,1,3]、[2,1、 3]、[1,3,4]。
促す:
1 <= A.length <= 20000
1 <= A[i] <= A.length
1 <= K <= A.length
問題解決
必要なのは、配列Aのk種類の整数で構成されている連続したサブ配列の数です。
分析:
k種類の整数なので、少なくとも長さはkで
あり、連続する必要があります
この種の要件では、ダブルポインター
を使用して最初からトラバースでき、左が左としてマークされ、右が右としてマークされます。
ダブルポインターを介してよく発生するのは、最大かつ最大の問題です。ここではまったく同じです。をkに変換するため、変換は次のようになります。最大k個の異なる整数を持つサブ配列の数は、最大k-1個の異なる整数を持つサブ配列の数を引くことによって取得できます。
テンプレート:
int subarraysWithKDistinct(int* A, int ASize, int K){
}
int subarraysWithKDistinct(int* A, int ASize, int K) {
int num1[ASize + 1], num2[ASize + 1];
memset(num1, 0, sizeof(int) * (ASize + 1));
memset(num2, 0, sizeof(int) * (ASize + 1));
int tot1 = 0, tot2 = 0;
int left1 = 0, left2 = 0, right = 0;
int ret = 0;
while (right < ASize) {
if (!num1[A[right]]) {
tot1++;
}
num1[A[right]]++;
if (!num2[A[right]]) {
tot2++;
}
num2[A[right]]++;
while (tot1 > K) {
num1[A[left1]]--;
if (!num1[A[left1]]) {
tot1--;
}
left1++;
}
while (tot2 > K - 1) {
num2[A[left2]]--;
if (!num2[A[left2]]) {
tot2--;
}
left2++;
}
ret += left2 - left1;
right++;
}
return ret;
}