微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何获得至少有 K 个不同数字的子数组的编号?

如何解决如何获得至少有 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 举报,一经查实,本站将立刻删除。