如何解决如何获得至少有 K 个不同数字的子数组的编号?
问题是: “给定一个只包含整数的数组 A 返回包含至少 k 个不同数字的子数组的数量。子数组不能重复。”
示例:
input array = {1,2,3,4,2} k = 3
output: 4
说明:
至少有K个不同数的子数组的个数应该是4, 它们是 [1,3] [2,4] [3,2] [1,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} k = 2 我的代码无法正常工作,但我不知道在哪里更改。有什么想法吗?谢谢!
更新:感谢@MBo 和其他人的回答,我使用了 2 个指针来解决这个问题,但仍然无法得到正确的答案: 数组 = {1,2} k = 3 -> 输出:6(应该是 4)
似乎有一些重复的子串被计算在内,但我不知道如何解决。
class Solution {
public static void main(String[] args) {
int[] A = {1,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
索引等重复。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。