如何获取至少有 K 个不同数字的子数组的编号?
How to get the number of the Subarray with at least K different numbers?
问题是:
“给定数组 A 仅包含整数 Return 包含至少 k 个不同数字的子数组的数量。子数组不能重复。”
示例:
input array = {1, 2, 3, 4, 2} k = 3
output: 4
解释:
至少有K个不同数的Subarray的个数应该是4个,
这是 [1, 2, 3] [2, 3, 4] [3, 4, 2] [1, 2, 3, 4]
现在我能做的就是找出正好有K个不同数字的子数组的数量:
class Solution {
public int subarraysWithKDistinct(int[] A, int K) {
return atMostK(A, K) - atMostK(A, K - 1);
}
private int atMostK(int[] A, int K) {
int i = 0, res = 0;
Map<Integer, Integer> count = new HashMap<>();
for (int j = 0; j < A.length; ++j) {
if (count.getOrDefault(A[j], 0) == 0) K--;
count.put(A[j], count.getOrDefault(A[j], 0) + 1);
while (K < 0) {
count.put(A[i], count.get(A[i]) - 1);
if (count.get(A[i]) == 0) K++;
i++;
}
res += j - i + 1;
}
return res;
}
}
但是当输入是:
数组 = {1, 2, 3, 4, 2} k = 2
我的代码将无法正常工作,但我不知道在哪里更改。有什么想法吗?谢谢!
更新:感谢@MBo 和其他人的回答,我使用了 2 个指针来解决这个问题,但仍然无法得到正确的答案:
array = {1, 2, 3, 4, 2} k = 3 -> 输出:6(应该是 4)
好像统计了一些重复的子串,但我不知道如何解决。
class Solution {
public static void main(String[] args) {
int[] A = {1, 2, 3, 4, 2};
int k = 3;
int res = helper(A, k);
System.out.println(res);
// output is 6, but should be 4
}
private static int helper(int[] A, int k) {
if (A == null || A.length == 0) return 0;
int n = A.length;
int res = 0;
int differentNumbers = 0;
Map<Integer, Integer> counter = new HashMap<>();
int j = 0; // j - 1 is the right point
for (int i = 0; i < n; i ++) {
while (j < n && differentNumbers < k) {
int numOfThisNumber = counter.getOrDefault(A[j], 0);
counter.put(A[j], numOfThisNumber + 1);
if (counter.get(A[j]) == 1) {
differentNumbers ++;
}
j ++;
}
if (differentNumbers == k) {
res += n - j + 1;
}
counter.put(A[i], counter.get(A[i]) - 1);
if (counter.get(A[i]) == 0) {
differentNumbers --;
}
}
return res;
}
}
您可以将 hashmap 方法与两个指针(索引)的方法结合起来。
将两个索引设置为 0 并将 right
移动一个,更新间隔 right
末尾处的值的散列图计数,直到散列图大小达到 K
。修复 right
索引。
现在移动 left
索引,减少对应于 left
末尾的值的计数。在每一步(包括left=0
)之前将size-right
添加到结果中,因为所有个子数组从left
开始并在right
之后结束,做包含所需数量的元素。
当某些计数变为 0
时,从 hashmap 中删除值,并修复 left
索引。
重复 right
索引等。
问题是: “给定数组 A 仅包含整数 Return 包含至少 k 个不同数字的子数组的数量。子数组不能重复。”
示例:
input array = {1, 2, 3, 4, 2} k = 3
output: 4
解释:
至少有K个不同数的Subarray的个数应该是4个, 这是 [1, 2, 3] [2, 3, 4] [3, 4, 2] [1, 2, 3, 4]
现在我能做的就是找出正好有K个不同数字的子数组的数量:
class Solution {
public int subarraysWithKDistinct(int[] A, int K) {
return atMostK(A, K) - atMostK(A, K - 1);
}
private int atMostK(int[] A, int K) {
int i = 0, res = 0;
Map<Integer, Integer> count = new HashMap<>();
for (int j = 0; j < A.length; ++j) {
if (count.getOrDefault(A[j], 0) == 0) K--;
count.put(A[j], count.getOrDefault(A[j], 0) + 1);
while (K < 0) {
count.put(A[i], count.get(A[i]) - 1);
if (count.get(A[i]) == 0) K++;
i++;
}
res += j - i + 1;
}
return res;
}
}
但是当输入是: 数组 = {1, 2, 3, 4, 2} k = 2 我的代码将无法正常工作,但我不知道在哪里更改。有什么想法吗?谢谢!
更新:感谢@MBo 和其他人的回答,我使用了 2 个指针来解决这个问题,但仍然无法得到正确的答案: array = {1, 2, 3, 4, 2} k = 3 -> 输出:6(应该是 4)
好像统计了一些重复的子串,但我不知道如何解决。
class Solution {
public static void main(String[] args) {
int[] A = {1, 2, 3, 4, 2};
int k = 3;
int res = helper(A, k);
System.out.println(res);
// output is 6, but should be 4
}
private static int helper(int[] A, int k) {
if (A == null || A.length == 0) return 0;
int n = A.length;
int res = 0;
int differentNumbers = 0;
Map<Integer, Integer> counter = new HashMap<>();
int j = 0; // j - 1 is the right point
for (int i = 0; i < n; i ++) {
while (j < n && differentNumbers < k) {
int numOfThisNumber = counter.getOrDefault(A[j], 0);
counter.put(A[j], numOfThisNumber + 1);
if (counter.get(A[j]) == 1) {
differentNumbers ++;
}
j ++;
}
if (differentNumbers == k) {
res += n - j + 1;
}
counter.put(A[i], counter.get(A[i]) - 1);
if (counter.get(A[i]) == 0) {
differentNumbers --;
}
}
return res;
}
}
您可以将 hashmap 方法与两个指针(索引)的方法结合起来。
将两个索引设置为 0 并将 right
移动一个,更新间隔 right
末尾处的值的散列图计数,直到散列图大小达到 K
。修复 right
索引。
现在移动 left
索引,减少对应于 left
末尾的值的计数。在每一步(包括left=0
)之前将size-right
添加到结果中,因为所有个子数组从left
开始并在right
之后结束,做包含所需数量的元素。
当某些计数变为 0
时,从 hashmap 中删除值,并修复 left
索引。
重复 right
索引等。