【问题标题】:Finding count of distinct elements in every k subarray查找每个 k 子数组中不同元素的计数
【发布时间】:2015-10-31 18:35:30
【问题描述】:

如何有效地解决这个问题?

给定一个大小为 n 的数组和一个整数 k,我们需要返回大小为 k 的窗口中所有不同数字的计数之和。窗口向前滑动。

例如arr[] = {1,2,1,3,4,2,3};

设 k = 4。

The first window is {1,2,1,3}, count of distinct numbers is 2….(1 is repeated)
The second window is {2,1,3,4} count of distinct numbers is 4
The third window is {1,3,4,2} count of distinct numbers is 4
The fourth window is {3,4,2,3} count of distinct numbers is 2

【问题讨论】:

  • 元素的期望值范围是多少?如果范围适中,您可以使用数组来注册给定值的存在。

标签: arrays algorithm integer distinct-values


【解决方案1】:

这就是我解决问题的方法

私有静态 int[] getSolve(int[] A, int B) {

    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < B; i++) {
        map.put(A[i], map.getOrDefault(A[i], 0) + 1);
    }

    List<Integer> res = new ArrayList<>();
    res.add(map.size());
    //4, 1, 3, 1, 5, 2, 5, 6, 7

    //3, 1, 5, 2, 5, 6     count = 5
    for (int i = B; i < A.length; i++) {

        if (map.containsKey(A[i - B]) && map.get(A[i - B]) == 1) {
            map.remove(A[i - B]);
        }
        if (map.containsKey(A[i - B])) {
            map.put(A[i - B], map.get(A[i - B]) - 1);
        }
        map.put(A[i], map.getOrDefault(A[i], 0) + 1);


        System.out.println(map.toString());
        res.add(map.size());
    }
    return res.stream().mapToInt(i -> i).toArray();
}

【讨论】:

    【解决方案2】:

    您可以使用哈希表H 在遍历数组时跟踪窗口。您还为哈希表中的每个条目保留一个附加字段,用于跟踪该元素在您的窗口中出现的次数。

    首先将arr 的第一个k 元素添加到H。然后遍历arr 的其余部分,并减少刚刚离开窗口的元素的计数器字段并增加进入窗口的元素的计数器字段。

    在任何时候(包括初始插入到H),如果计数器字段变为1,您就会增加窗口中不同元素的数量。这可能发生在元素的最后一次出现离开窗口或第一次出现进入窗口时。如果计数器字段变为除1 之外的任何其他值,则您会减少窗口中不同元素的数量。

    这是arr 中元素数量的线性解。散列整数可以像this 一样完成,但根据您用于实现解决方案的语言,您可能不需要自己对它们进行散列。如果arr 的元素所在的范围足够小,您可以按照其他贡献者的建议使用简单的数组代替哈希表。

    【讨论】:

      【解决方案3】:

      其实我是提问者,我不是在回答问题,只是想对答案发表评论,但我不能,因为我的声望很低。

      我认为对于 {1, 2, 1, 3} 和 k = 4,给定的算法产生 count = 3,但根据问题,计数应该是 2(因为重复 1)

      【讨论】:

      • 好的。我同意。我最初的解决方案是解决一个稍微不同的问题。检查我的更新。
      【解决方案4】:

      你应该跟踪

      • 统计窗口中元素频率的地图
      • 当前总和。

      如果可能的元素来自有限的集合,则带有频率的地图也可以是一个数组。

      那么当你的窗口向右滑动时……

      1. 将新数字的频率增加 1。
      2. 如果该频率现在为 1,则将其添加到当前总和中。
      3. 将旧数字的频率降低 1。
      4. 如果该频率现在为 0,则从当前总和中减去它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-24
        • 2019-07-10
        • 2021-01-13
        • 2021-11-07
        • 2015-03-07
        • 2015-08-10
        • 2018-04-20
        相关资源
        最近更新 更多