[Leetcode]930.和相同的二元子数组+992.K个不同整数的子数组 关键词:[子数组][滑窗]

文章目录

  • Leetcode 992
    • 方法一:滑窗右端每次+1,左端来回滑动
    • 方法二:(最多K种的子串数) - (最多K-1种的子串数) = 恰好K种
  • Leetcode 930
    • 方法一:(最多和为goal的子串数) - (最多和为goal-1的子串数) = 恰好和为goal
    • 方法二:解释一下抽象的官解

Leetcode 992

在这里插入图片描述
1 <= nums.length <= 20000
1 <= nums[i], k <= nums.length

方法一:滑窗右端每次+1,左端来回滑动

这道题初步看上去像滑窗。滑窗解决的问题是“最长”,比如找“无重复字符的最长子串”、“特定排列的子串”。通用方法就是滑窗右侧尽可能向右,直到滑窗内元素的个数不满足要求那么滑窗左侧右移。

本题考虑的不是“最多K个不同整数”,而是“恰好K个不同整数”。

我的办法(方法一)是先用滑窗找到“最多K个不同整数”的每个左右边界,然后对于这其中的每一个右边界,左边界“尝试右移”,找到全部合适的左边界。比如序列12123,对于第二个2来说,“最多2个不同整数”,就是1212,满足条件的左边界有3个,[1]212、[2]12、[1]2.

具体到代码实现,对于每一个右边界(即将加入滑窗)的值来说:

  1. 如果这个值曾经在滑窗中出现过,则把该值加入滑窗之后,滑窗内仍然是恰好K种数,那么pl“尝试右移”:cnt数组相应减少,直到遇到第一个将cnt的某个非零值减到0位置的位置tmp_pl,那么tmp-pl就是此时右边界对应所有左边界的个数。然后把pl~tmp_pl区间内的数再加回cnt数组(恢复)。
  2. 如果这个值没有在滑窗中出现,那么把该值加入滑窗之后,滑窗内就有K+1种数了,此时pl必须右移。右移到合适位置后,再进行1中的“尝试右移”操作。
class Solution {
    int cnt[20010] = {0};
    int ans = 0;

public:
    int subarraysWithKDistinct(vector<int>& nums, int k) {
        int pl = 0, pr = 0, k2 = 0;

        // 先找k个不同的,定下初始滑窗位置 左闭右开
        for (; pr < nums.size() && k2 < k; pr++)
            if (++cnt[nums[pr]] == 1) k2++;
        
        if (k2 < k) return 0;
        ans++;

        // 开始滑动
        while (pr < nums.size()) {
            // 先尝试pl右移
            int tmp_pl = pl;
            while (cnt[nums[tmp_pl]] > 1) {
                ans++;
                cnt[nums[tmp_pl]]--; tmp_pl++;
            }
            // 恢复
            while (tmp_pl > pl) {
                tmp_pl--;
                cnt[nums[tmp_pl]]++;
            }

            // if 下一个数是旧数,加入
            if (cnt[nums[pr]] > 0) {
                cnt[nums[pr]]++; pr++;
                ans++;
            }
            // if 下一个数是新数,pl右移至窗内种类数-1
            else {
                cnt[nums[pr]]++; pr++;
                do {
                    cnt[nums[pl]]--;
                    pl++;
                } while (cnt[nums[pl - 1]] > 0);
                ans++;
            }
        }

        // 尝试pl右移
        int tmp_pl = pl;
        while (cnt[nums[tmp_pl]] > 1) {
            ans++;
            cnt[nums[tmp_pl]]--;
            tmp_pl++;
        }
        return ans;
    }
};

时间复杂度:最坏是Onn,但是实际还不错。
在这里插入图片描述

方法二:(最多K种的子串数) - (最多K-1种的子串数) = 恰好K种

这个方法是官方题解法。

还是12123,且K=2这个例子,对于1212来说,有3个左边界可以满足“恰好K种”,这个3是怎么算出来的呢?最多K-1种的左边界是1个,一共4个潜在的左边界,4-1=3.

(最多K种的子串数) - (最多K-1种的子串数) = 恰好K种

时间复杂度On
代码和下面这道题是几乎一模一样的

Leetcode 930

在这里插入图片描述

方法一:(最多和为goal的子串数) - (最多和为goal-1的子串数) = 恰好和为goal

就是992题的方法二

// 本题跟992非常类似,可以用一模一样的方法。O(n)
class Solution {
    int f(vector<int>& nums, int goal) {
        if (goal < 0) return 0;
        int cnt = 0; // 滑窗内1的个数。因为数组内只有0或1,所以用一个变量就能存滑窗内的值。
        int pl = 0, pr = 0, ans = 0;
        while (pr < nums.size()) {
            cnt += nums[pr];
            pr++;

            // 看是否需要缩小滑窗范围
            while (cnt > goal) {
                cnt -= nums[pl];
                pl++;
            }
            ans += (pr - pl);
        }
        return ans;
    }

public:
    int numSubarraysWithSum(vector<int>& nums, int goal) {
        return f(nums, goal) - f(nums, goal - 1);
    }
};

在这里插入图片描述

方法二:解释一下抽象的官解

这个官解抽象得令人发指,下面我来解释一下,此题跟哈希表有啥关系、跟前缀和有啥关系。

在这里插入图片描述
在这里插入图片描述
还是回来考虑,对于每一个固定的右边界。符合要求的左边界有几个。比如样例的序列10101——
对于右边界是下标2,符合要求的子序列是[101]01——1种
对于右边界是下标3,符合要求的子序列是[1010]1——1种
而对于右边界是下标4,符合要求的子序列是1[0101] 10[101]——2种
总共是4种.

拿右边界是下标4的举例子,这个2种怎么来的?从下标0到下标4,前缀和为3,也就是从开始到现在,已经看见3个1了,我的目标是看见2个1,那么减去前缀和是1的情况就可以了。

所以官解里用了map<key, value> 维护前缀和是key的种类数有value个。
对于每一个右边界,看到它位置遇见的1比goal多了几个,减去map中记录的值即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/477833.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

移动app测试的好处简析,有必要选择第三方软件测试机构吗?

移动app测试是指对移动应用程序进行全面、系统和深入的检查和验证&#xff0c;以确保其功能、性能和稳定性达到预期要求。在移动应用市场日益竞争激烈的今天&#xff0c;进行移动app测试是至关重要的。 一、移动app测试的好处&#xff1a;   1、具有确保应用质量的作用。通过…

Linux 在线yum安装: PostgreSQL 15.6数据库

Linux 在线yum安装&#xff1a; PostgreSQL 15.6数据库 1、PostgreSQL数据库简介2、在线安装PostgreSQL15.63、配置 PostgreSQL的环境变量4、使用默认用户登录PostgreSQL5、配置 PostgreSQL 允许远程登录6、修改 PostgreSQL 默认端口7、创建数据库和表、远程用户zyl8、pgAdmin远…

基于Java的APK检测管理系统(Vue.js+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 开放平台模块2.3 软件档案模块2.4 软件检测模块2.5 软件举报模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 开放平台表3.2.2 软件档案表3.2.3 软件检测表3.2.4 软件举报表 四、系统展示五、核心代…

机器学习-06-无监督算法-02-层次聚类和密度聚类DBSCAN算法

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中无监督算法&#xff0c;包括层次和密度聚类等。 参考 DBSACN在线动态演示 本门课程的目标 完成一个特定行业的算法应用全过程&#xff1a; 懂业务会选择合适的算法数据处理算法训练算法调优算法融合 算…

摸鱼小技巧来啦,速来围观

一、前言 在日常测试中&#xff0c;很多小伙伴还是选择使用usb连接设备的方式去进行跑测&#xff0c;当需要连接多台设备就没办法在电脑上插入这么多设备&#xff0c;只能选择使用无线连接的方式去进行连接测试。你们快来get这份详细的无线连接设备教程吧~ 二、远程连接Andro…

demo版多人聊天系统

目录 ​编辑 一&#xff0c;引入 二&#xff0c;在Server端修改的代码 1&#xff0c;保存用户信息功能实现 2&#xff0c;拼接消息 3&#xff0c;广播消息 三&#xff0c; Client端要修改的代码 四&#xff0c;效果演示 一&#xff0c;引入 在上一篇文章udp网络服务器中&a…

LLM+Embedding构建问答系统的局限性及优化方案

LangChain LLM 方案的局限性&#xff1a;LLM意图识别准确性较低&#xff0c;交互链路长导致时间开销大&#xff1b;Embedding 不适合多词条聚合匹配等。 背景 在探索如何利用大型语言模型&#xff08;LLM&#xff09;构建知识问答系统的过程中&#xff0c;我们确定了两个核心…

飞跃前端瓶颈:技术进阶指南精华篇

引言&#xff1a; 在互联网的快车道上&#xff0c;前端技术日新月异。对于前端工程师而言&#xff0c;技术水平达到一定高度后&#xff0c;往往会遭遇成长的天花板。本文将探讨如何识别并突破这些技术瓶颈&#xff0c;分享实用的进阶策略和实践案例。 一、技术等级概览&#xf…

python知识点总结(七)

python知识点总结七 1、堆和栈的区别2、如何在局部修改全局的变量a、计算结果b、计算结果 3、如何修改一个enclosing变量4、关于值传递还是地址传值5、布尔类型6、逻辑运算7、字符串切片操作8、取整、取余、除数9、变量赋值10、字符串与数字相乘11、整型、浮点型、字符型之间相…

【LVGL-特殊符号】

LVGL-特殊符号 ■ LVGL-特殊符号 ■ LVGL-特殊符号 /* 直接调用 */ lv_label_set_text(my_label, LV_SYMBOL_OK); /* 与字符一起用 */ lv_label_set_text(my_label, LV_SYMBOL_OK "Apply"); /* 多个符号一起用 */ lv_label_set_text(my_label, LV_SYMBOL_OK LV_SYMBO…

智过网:一级建造师必须两年考过吗?有效期多久?

在建筑行业&#xff0c;一级建造师的职业资格证书是众多从业者追求的目标。然而&#xff0c;获得这一证书并非易事&#xff0c;它要求考生不仅具备扎实的专业知识&#xff0c;还需要在限定的时间内完成所有科目的考试。那么&#xff0c;一级建造师是否必须在两年内考完所有科目…

LeetCode - 存在重复元素

219. 存在重复元素 II 这道题可以用两个方法解决。 哈希表 从左到右遍历数组&#xff0c;并将数组的下标存到hash中&#xff0c;在遍历数字的过程中&#xff0c;如果hash中不存在nums[i]&#xff0c;将nums[i]加入到hash当中&#xff0c;若存在&#xff0c;则判断下标之间的关…

九泰智库 | 医械周刊- Vol.16

⚖️ 法规动态 28类耗材联盟集采结果出炉&#xff0c;中选率仅27% 3月19日&#xff0c;河北省药械集采中心发布了《关于公示京津冀“3N”联盟28种集中带量采购医用耗材拟中选结果的通知》。共有202个产品被列为拟中选&#xff0c;产品中选率约为27%。本次集采未设置保底中标条…

buuctf_Reverse_wp_2

文章目录 [WUSTCTF2020]level3[base64变表]Youngter-drive[upx、多线程][FlareOn4]IgniteMe[算法分析]相册[APK、so文件、Native方法][WUSTCTF2020]Cr0ssfun[套娃、patience][GWCTF 2019]xxor[z3、算法分析][UTCTF2020]basic-re[FlareOn6]Overlong脚本输出动态调试 [FlareOn3]C…

科技强国:国产桌面操作系统正式上线,中国七位院士发表支持

操作系统是电子产品的核心&#xff0c;无论是手机还是电脑&#xff0c;都离不开它的支持。它是科技发展中至关重要的领域之一。备受瞩目的鸿蒙系统&#xff0c;作为国内颇具影响力的手机桌面操作系统&#xff0c;以其桌面组件自由整合和自定义风格的便捷性&#xff0c;引领了一…

运用YOLOv5实时监测并预警行人社交距离违规情况

YOLO&#xff08;You Only Look Once&#xff09;作为一种先进的实时物体检测算法&#xff0c;在全球范围内因其高效的实时性能和较高的检测精度受到广泛关注。近年来&#xff0c;随着新冠疫情对社交距离管控的重要性日益凸显&#xff0c;研究人员开始将YOLO算法应用于社交距离…

5G安全技术新突破!亚信安全5G安全迅龙引擎正式发布

5G专网应用飞速增长&#xff1a;2020年5G专网数量800个&#xff0c;2021年2300个&#xff0c;2022年5325个&#xff0c;2023年已经超过16000个&#xff0c;5G与垂直行业的融合快速加深&#xff0c;5G带来的变革正加速渗透至各行各业。 5G网络出现安全问题&#xff0c;将是异常严…

QT tableWidget横向众向设置

横向控件 要设置QTabWidget选项卡的字体方向&#xff0c;可以使用QTabWidget的setTabPosition()方法。通过传递Qt枚举值QTabWidget.east或QTabWidget.west作为参数&#xff0c;可以设置选项卡的字体方向为从左到右或从右到左。 myTabWidget QTabWidget() myTabWidget.setTabP…

【论文精读】DALLE3:Improving Image Generation with Better Captions 通过更好的文本标注改进图像生成

文章目录 一、文章概览二、数据重标注&#xff08;一&#xff09;现在训练数据的文本标注主要存在的问题&#xff08;二&#xff09;创建图像标注器&#xff08;三&#xff09;微调图像标注器 三、评估重新标注的数据集&#xff08;一&#xff09;混合合成标注和真实标注&#…

【vue】vue中的路由vue-router,vue-cli脚手架详细使用教程

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…
最新文章