热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

每日算法系列【LeetCode992】K个不同整数的子数组

题目描述给定一个正整数数组A,如果A的某个子数组中不同整数的个数恰好为K,则称A的这个连续、不一定独立的子数组为好子数组。(例如ÿ

题目描述

给定一个正整数数组 A,如果 A 的某个子数组中不同整数的个数恰好为 K,则称 A 的这个连续、不一定独立的子数组为好子数组。 (例如,[1,2,3,1,2] 中有 3 个不同的整数:1,2,以及 3。)

返回 A 中好子数组的数目。

示例1

输入:
A = [1,2,1,2,3], K = 2
输出:
7
解释:
恰好由 2 个不同整数组成的子数组:
[1,2], [2,1], [1,2], [2,3], [1,2,1], [2,1,2], [1,2,1,2]

示例2

输入:
A = [1,2,1,3,4], K = 3
输出:
3
解释:
恰好由 3 个不同整数组成的子数组:
[1,2,1,3], [2,1,3], [1,3,4]

提示

  • 1 <&#61; A.length <&#61; 20000
  • 1 <&#61; A[i] <&#61; A.length
  • 1 <&#61; K <&#61; A.length

题解

这题最暴力的方法就是用一个字典维护每个数出现的次数&#xff0c;然后遍历所有的区间&#xff0c;求出不同整数个数正好等于 K 的区间个数。 但是这种方法时间复杂度是 O(n^2)&#xff0c;一定会超时&#xff0c;所以考虑其他方法。

现在考虑右边界为 j 的情况&#xff0c;左边界 i 有什么规律呢&#xff1f; 我们可以证明&#xff0c;满足 [i, j] 正好包含 K 个不同整数的 i 的取值是一段连续的区间。 假设 [i, j]包含 K 个不同整数&#xff0c;同时 [i&#39;, j] 也包含 K 个不同整数&#xff08;i

有了这个性质之后&#xff0c;对于任意的 j &#xff0c;我们只需要求出左边界 i 的取值范围就行了。同样这里还是不能暴力求&#xff0c;不然就和一开始没区别了嘛。 既然这样&#xff0c;想想如果 j 的左边界 i 的范围得到了&#xff0c;这时候我们继续求 j &#43; 1 的左边界范围&#xff0c;能不能利用一下之前得到的结果&#xff1f;而不用重新计算。 很容易发现&#xff0c;如果 j 右移了&#xff0c; i 的取值范围也会右移&#xff0c;因为 j 右移有两种结果&#xff1a;一是引入了新的数&#xff0c;二是某个存在的数的数量加 1 。 第一种情况对左边界没有任何影响&#xff0c;因为不同整数数量没有变化&#xff0c;还是 K 。第二种情况不同整数数量变成 K &#43; 1 了&#xff0c;这时候左边界一定要右移&#xff0c;删掉点数&#xff0c;才可能使区间符合题意。

有了上述的性质之后就好做了&#xff0c;因为左边界的取值范围也是不断右移的&#xff0c;所以我们只需要维护两个指针 l 和 r 就行了&#xff0c;一个保存取值范围的最小值&#xff0c;一个保存最大值。然后每次对于一个 j &#xff0c;符合题意的子区间数量就是 r - l &#43; 1 。而 j 右移一个数之后&#xff0c; l 需要右移&#xff0c;直到 [l, j] 中正好有 K 个不同整数&#xff0c; r 也继续右移&#xff0c;直到[r &#43; 1, j] 中正好有 K - 1 个不同整数。

因为 l 和 r 最多只会移动 n 次&#xff0c;而 j 也只移动了 n 次&#xff0c;所以总体时间复杂度降到了 O(n)

代码

c&#43;&#43;

class Solution {
public:int subarraysWithKDistinct(vector<int>& A, int K) {int n &#61; A.size();int cl[n&#43;1], cr[n&#43;1], l &#61; 0, r &#61; 0;int res &#61; 0, nl &#61; 0, nr &#61; 0;memset(cl, 0, sizeof cl);memset(cr, 0, sizeof cr);for (int i &#61; 0; i < n; &#43;&#43;i) {if (cl[A[i]]&#43;&#43; &#61;&#61; 0) nl&#43;&#43;;while (nl > K) {if (--cl[A[l&#43;&#43;]] &#61;&#61; 0) nl--;}if (cr[A[i]]&#43;&#43; &#61;&#61; 0) nr&#43;&#43;;while (nr >&#61; K) {if (--cr[A[r&#43;&#43;]] &#61;&#61; 0) nr--;}res &#43;&#61; r - l;}return res;}
};

python

class Solution:def subarraysWithKDistinct(self, A: List[int], K: int) -> int:n &#61; len(A)cl &#61; [0] * (n&#43;1)cr &#61; [0] * (n&#43;1)l &#61; r &#61; nl &#61; nr &#61; res &#61; 0for i in range(n):if cl[A[i]] &#61;&#61; 0:nl &#43;&#61; 1cl[A[i]] &#43;&#61; 1while nl > K:cl[A[l]] -&#61; 1if cl[A[l]] &#61;&#61; 0:nl -&#61; 1l &#43;&#61; 1if cr[A[i]] &#61;&#61; 0:nr &#43;&#61; 1cr[A[i]] &#43;&#61; 1while nr >&#61; K:cr[A[r]] -&#61; 1if cr[A[r]] &#61;&#61; 0:nr -&#61; 1r &#43;&#61; 1res &#43;&#61; r - lreturn res

后记

其实这题想起来可能好想&#xff0c;但是写起来容易写错&#xff0c;因为区间范围需要好好琢磨。这一类问题统称为“窗口滑动”问题&#xff0c;都是不特别难&#xff0c;想清楚了两个状态之间窗口如何滑动就行了。



推荐阅读
  • 漫画:位运算系列篇(只出现一次的数字)
    今天是小浩算法“365刷题计划”第62天。仍然分享一道关于位运算颇为简单的题型,同时,从明天开始将会提高难度,大家做好准备。01PARTS ... [详细]
  • 我正在用python构建纸牌游戏(与Dobbel类似,如果您知道的话)。游戏在纸牌组中 ... [详细]
  • 1.Python1.数据类型1.数字整形:int浮点型:float复数型:complex布尔型:bool2.字符串字符串:String3.与 ... [详细]
  • 图像处理(7) : 边缘检测
    边缘检测是图形图像处理、计算机视觉和机器视觉中的一个基本工具,通常用于特征提取和特征检测,旨在检测一张数字图像中有明显变化的边缘或者不连续的区域 ... [详细]
  • Day 5 20190120 老男孩python学习第5天 内容整理
    今天继续看MasteringPycharm的视频,一个半小时看git的教学视频:视频1小时44分钟,看了2个半小时以上https:www.youtube ... [详细]
  •  d.keys()1.作用:获取字典d中的所有key值,返回值是一个对象2.例子:dict1dict(one1,two2)print(dict1.keys())  输出结果为:   ... [详细]
  • PyQt 如何创建自定义QWidget
    这篇文章主要介绍了PyQt如何创建自定义QWidget,帮助大家更好的理解和学习使用pyqt,感 ... [详细]
  • #元组是不可变的列表用法和列表基本相似#元组使用小括号()#元组的读和写t(a,b,c)print(t[2])#写入的函数同样不被支持,但是如果 ... [详细]
  • 文章目录问题原因解决list.remove方法在删除元素的时候往往会出现漏删或者索引越界的情况。问题给定了一个日期列表(我这边用于判定文件夹是否存在)。dateList[202 ... [详细]
  • Python多进程遇到的问题
    多进程共享对象我有一个IpConnectionPool对象需要多个进程共享创建BaseManager注册Ip ... [详细]
  • TLB 缓存延迟刷新漏洞 CVE201818281 解析 ... [详细]
  • 每日一书丨AI圣经《深度学习》作者斩获2018年图灵奖
    2019年3月27日——ACM宣布,深度学习之父YoshuaBengio,YannLeCun,以及GeoffreyHinton获得了2018年的图灵奖, ... [详细]
  • 1、对于List而言,要不然就使用迭代器,要不然就从后往前删除,从前往后删除会出现角标越界。因为我List有两个remove方法,一个是int作为形参(删除指定位置的元素),一个是 ... [详细]
  • AI开发选择哪种编程语言?如果您是新手AI开发人员,您可能很难选择用于开发AI的编程语言。虽然有很多可用的编程语言,但我会将注意力集中在Python和 ... [详细]
  • 1011-MarriageCeremoniesPDF(English)StatisticsForumTimeLimit:2second(s)MemoryLimit:32MBYouw ... [详细]
author-avatar
王瑾瑜2702935333
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有