滑动窗口打印恰好K个不同元素子数组时遗漏结果如何解决
问题分析
你的代码逻辑的核心问题是:滑动窗口的左边界是单调右移的,一旦收缩就不会回到之前的位置,因此只能统计每个右边界对应的、左边界尽可能靠右的合法子数组,会遗漏左边界更靠左的、同样满足恰好K个不同元素的子数组。
你漏掉的[1,2,1,2]这个子数组,就是因为当右边界走到下标3(也就是第四个元素2)时,你的左边界已经在之前的循环中被收缩到了下标1的位置,永远不会再回到下标0,因此这个从下标0开始到3结束的合法子数组永远不会被你的代码捕捉到。
解决方案
要输出所有符合条件的子数组,有两种常见实现方案:
方案1:枚举左边界(简单直观,适合小规模数组)
固定左边界后,逐步扩张右边界,直到窗口内不同元素数量超过K,过程中只要窗口内不同元素数量等于K就输出当前子数组。
代码实现如下:
import java.util.*; public class Main { public static void main(String[] args) { int[] A = {1, 2, 1, 2, 3}; int K = 2; int n = A.length; for (int left = 0; left < n; left++) { Map<Integer, Integer> countMap = new HashMap<>(); List<Integer> subArray = new ArrayList<>(); for (int right = left; right < n; right++) { int num = A[right]; countMap.put(num, countMap.getOrDefault(num, 0) + 1); subArray.add(num); if (countMap.size() == K) { System.out.println(subArray); } else if (countMap.size() > K) { break; } } } } }
方案2:双滑动窗口(时间复杂度O(n),适合大规模数组)
利用「恰好K个不同元素的子数组 = 最多K个不同元素的子数组 - 最多K-1个不同元素的子数组」的思路,维护两个滑动窗口分别记录最多K个和最多K-1个不同元素的左边界,对于每个右边界,所有左边界落在两个左边界区间内的子数组都符合要求,直接输出即可。
运行结果
上述代码运行后会输出所有符合要求的子数组:
[1, 2] [1, 2, 1] [1, 2, 1, 2] [2, 1] [2, 1, 2] [1, 2] [2, 3]
内容的提问来源于stack exchange,提问作者souparno majumder
相关产品推荐
相关产品推荐

