3. 无重复字符的最长子串/438. 找到字符串中所有字母异位词/560. 和为 K 的子数组

3. 无重复字符的最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

思路:想象一下我们自己是怎么判断无重复的,先以第K个字符开始,依次加入字符,直到遇到重复的,这里抽象成代码语言就是:需要两个指针(左右指针去移动),还需要一个能存储字符的数据结构,并且可以判断重复。所以我们就可以采用滑动窗口去处理,对于判断重复用的数据结构为哈希集合(即 C++ 中的 std::unordered_set

        在左指针向右移动的时候,我们从哈希集合中移除一个字符,在右指针向右移动的时候,我们往哈希集合中添加一个字符。

由上面想法可以写出下面代码(个人走的弯路,不想看可以跳过)

class Solution {
public:int lengthOfLongestSubstring(string s) {unordered_set<char> str;int right=0;//右值针int lenght=0;//最大长度for(int i=0;i<s.size();i++){str.insert(s[i]);right=i+1;while(!str.count(s[right])&&right<s.size()){str.insert(s[right]);++right;}lenght=max(lenght,right-i);right=i;str.clear();}return lenght;}
};

可以解出来,但是耗时太长没有利用好滑动窗口减少比对次数

        我们继续优化,减少比对次数,实际上每次左值针更新时,右指针可以不用左值针处开始比较,可以先将左值针移动向里收缩,右指针不动。

        原因:假设我们选择字符串中的第 k 个字符作为起始位置,并且得到了不包含重复字符的最长子串的结束位置为 rk​。那么当我们选择第 k+1个字符作为起始位置时,首先从 k+1到 rk的字符显然是不重复的,并且由于少了原本的第 k 个字符,我们可以尝试继续增大 rk (而不是从左值针处开始),直到右侧出现了重复字符为止。

优化代码:

class Solution {
public:int lengthOfLongestSubstring(string s) {unordered_set<char> str;int right=0;//右值针int lenght=0;//最大长度for(int i=0;i<s.size();i++){if(i!=0){str.erase(s[i-1]);}while(!str.count(s[right])&&right<s.size()){str.insert(s[right]);++right;}lenght=max(lenght,right-i);}return lenght;}
};

438. 找到字符串中所有字母异位词

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。

示例 1:

输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。

思路:用滑动窗口在S中找到和p的异位词就行,滑动过程中维持滑动窗口的长度等于P的长度。

PS:这里开始我用49. 字母异位词分组同样的方法,利用排序找出p字符串和滑动窗口的key,再进行比较,发现力扣有些变态测试用例会严重超时。其他测试用例都可以通过。代码如下(仅供参考):

class Solution {
public:vector<int> findAnagrams(string s, string p) {vector<int> nums;sort(p.begin(),p.end());int left=0,right=p.size();while((left+right)<=s.size()){string result=s.substr(left,right);sort(result.begin(),result.end());if(result==p){nums.emplace_back(left);}++left;}return nums;}
};

继续优化,耗时的原因就是排序,所以换成通过统计滑动窗口中字母出现的次数来判断是否和P是异位词。最后一个小细节,如果字符串s的长度小于字符串p的长度,直接返回空。

代码:

class Solution {
public:vector<int> findAnagrams(string s, string p) {int sL=s.size(),pL=p.size();if(sL<pL){//匹配字符串没有异位词长度大return vector<int>();}vector<int> nums;vector<int> snums(26);vector<int> pnums(26);for (int i = 0; i < pL; ++i) {//统计滑动窗口刚开始,内部包含的字母数量,相当于初始化滑动窗口++snums[s[i] - 'a'];++pnums[p[i] - 'a'];}if (snums == pnums) {nums.emplace_back(0);//如果滑动窗口启动时就匹配,说明位置0就是一个答案}for (int i = 0; i < sL - pL; ++i) {--snums[s[i] - 'a'];//滑动窗口左侧抛出++snums[s[i + pL] - 'a'];//滑动窗口右侧加入if (snums == pnums) {nums.emplace_back(i + 1);//注意i位置是被抛出滑动窗口的,匹配成功应该记录i的下一个位置}}return nums;}
};

560. 和为 K 的子数组

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 

子数组是数组中元素的连续非空序列。

示例 1:

输入:nums = [1,1,1], k = 2
输出:2

示例 2:

输入:nums = [1,2,3], k = 3
输出:2

思路:注意这里子数组是连续的序列,所以不存在跳着组合加起来等于k。看到连续数组和就用前缀和去处理(前缀和不在这里介绍)。

前缀和数组中有两种情况,一是本身就等于k,二是存在两个前缀和相减等于k。

对于上述两种情况,需要用map数组去统计前缀和出现的次数

为什么呢?

首先对于情况一,直接输出等于k的前缀和出现的次数,所以遍历前缀和时用map去统计出现次数;

对于情况二,我们举一个例子,如下 

可以看到对于情况二,如果前缀和出现相等时,那么符合条件的子数组个数就等于该前缀和出现的次数。例如前缀和0出现次数等于2,所以符合结果的子数组次数也是2,到这里就可以发现为什么要用map统计前缀和出现的次数,用代码表示就是

sum//当前前缀和
sum-k//符合条件的前缀和
map.count(sum-k)//map中符合条件的前缀和是否出现
res+=map[sum-k];//统计map中符合条件的前缀和出现次数

最后整合情况一和情况二,对于情况一来说前缀和sum等于K,所以我们初始化时候,map[0]=1,这样只要符合前缀和出现时候,map[sum-k]就是map[0]出现次数,这样就将情况一和情况二整合了。

代码:

class Solution {
public:int subarraySum(vector<int>& nums, int k) {unordered_map<int,int> map;//存放前缀和int sum=0;//当前前缀和int res=0;map[0]=1;for(auto n:nums){sum+=n;//计算前缀和if(map.count(sum-k)){res+=map[sum-k];}map[sum]++;//当前前缀和次数加一}return res;}
};

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

90天精通Psim仿真--经典实战教程--第10天 Simcode DSP28335 LED控制

PSIM (Power Simulation) 是一款电力电子和电机控制仿真软件,而DSP28335是德州仪器(TI)的一款数字信号处理器(DSP)。如果你想要在PSIM的SimCoder环境中为DSP28335生成LED闪烁的代码,遵循以下步骤: 打开PSIM并创建模型: 首先,在PSIM中创建一个电路模型,该模型应包括DS…

贪心(贪婪)算法

主要思想 贪心算法的思想主要可以概括为“总是做出当前看起来最优的选择”&#xff0c;也就是不从整体上进行考虑&#xff0c;所得到的答案是某种意义上的局部最优解&#xff0c;不一定是整体最优解。 贪心算法没有固定算法框架&#xff0c;算法设计的关键是贪心策略的选择。…

【回溯】Leetcode 22. 括号生成【中等】

括号生成 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;[“((()))”,“(()())”,“(())()”,“()(())”,“()()()”] 解题思路 1、使用回溯…

AI原生时代,操作系统为何是创新之源?

一直以来&#xff0c;操作系统都是软件行业皇冠上的明珠。 从上世纪40、50年代&#xff0c;汇编语言和汇编器实现软件管理硬件&#xff0c;操作系统的雏形出现&#xff1b;到60年代&#xff0c;高级编程语言和编译器诞生&#xff0c;开发者通过操作系统用更接近人的表达方式去…

Vue 组件通信的几种方式

vue通信方式简介 在Vue.js中&#xff0c;组件间通信可以通过props、$emit、事件总线、Vuex以及Provide/Inject等方式来实现&#xff0c;总的来说&#xff0c;组件通信是现代前端开发中不可或缺的一部分&#xff0c;它可以帮助开发者构建更加模块化、可维护和可扩展的应用。 Pr…

2024年4月18号技术面试总结

1.什么是微服务雪崩?微服务雪崩的解决方案? 微服务调用链路中的某个服务故障,引起整个链路中的所有微服务都不可用,这就是雪崩。服务A依赖于服务B,服务A依赖于服务D。现在假设,服务D出现了故障! 它访问这个服务D就必然要等待服务D的结果,那因为服务D出现了故障,那必然不…

String str=“hello“与String str = new String(“hello“)的区别

常量池&#xff08;constant pool&#xff09;指的是在编译期被确定&#xff0c;并被保存在以编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量&#xff0c;也包括字符串常量。 实际上 String str new String("hellow");创建了两个对象&#xf…

Java语言中字符串处理最常见的操作以及注意事项

0. 前言 由于最近线上连续出现跟字符串处理相关的故障&#xff0c;实属不应该。也从这些故障中看到大家对常见的字符串处理API有一些淡忘&#xff0c;希望通过收集整体并总结常见的处理方法&#xff0c;大家温故而知新。 1. 创建和初始化&#xff1a; a. 使用双引号直接创建…

方程豹春季品牌发布会:全家族矩阵献礼比亚迪

春意盎然的四月&#xff0c;深圳也迎来了中国新能源汽车领域的一场盛事。 4月16日&#xff0c;作为比亚迪旗下全球首个专业个性化汽车品牌&#xff0c;方程豹在深圳隆重举办春季发布会。 在这场以“方华”为主题的发布会上&#xff0c;方程豹汽车全家族矩阵首次集体亮相&#x…

【数据结构】单链表经典算法题的巧妙解题思路

目录 题目 1.移除链表元素 2.反转链表 3.链表的中间节点 4.合并两个有序链表 5.环形链表的约瑟夫问题 解析 题目1&#xff1a;创建新链表 题目2&#xff1a;巧用三个指针 题目3&#xff1a;快慢指针 题目4&#xff1a;哨兵位节点 题目5&#xff1a;环形链表 介绍完了…

美化博客文章(持续更新)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;游戏实现&#xff1a;贪吃蛇​​​​​​ &#x1f337;追光的人&#xff0c;终会万丈光芒 前言&#xff1a; 该文提供我的一些文章设计的一些方法 目录 1.应用超链接 1.应用超链接

IIL IIH

IIH test_no;DATALOG_MSG;TEST_NO(test_no);RELAY_ON PDCL资源FORCE_V_MLDPS给VCC上电5.5vPIN_MODE位leakage_PINS管脚组接地LEVELS(Vcc5d5_lvl,2mS); PIN_INC(leakage_PINS, LOOP_BY_PIN) { RELAY_OFF PDCL资源 RELAY_ON PPMU资源 FORCE_V_PPMU上电5.5v&#xff0c;电流量…

mysql in查询优化

都说in查询比较慢&#xff0c;要改成子查询模式&#xff0c;ChatGPT大模型告诉了我&#xff0c;SQL中替换In查询的10种方法&#xff0c;太赞了&#xff0c;按照这个说的集中方法&#xff0c;验证一下。因为实际项目中确实存在in很多的情况。 查询执行的先后顺序对优化有必要&am…

【EI会议征稿】2024年先进机械电子、电气工程与自动化国际学术会议(ICAMEEA 2024)

2024 International Conference on Advanced Mechatronic, Electrical Engineering and Automation ●会议简介 2024年先进机械电子、电气工程与自动化国际学术会议&#xff08;ICAMEEA 2024&#xff09;将汇聚全球机械电子、电气工程与自动化领域的专家学者&#xff0c;共同…

【软考】敏捷方法

目录 一、概念二、敏捷方法2.1 极限编程(XP)2.2 水晶法(Crystal)2.2.1 说明2.2.1 特征 2.3 并列争球法(Scrum)2.4 自适应软件开发(ASD)2.5 敏捷统一过程(AUP)2.5.1 说明2.5.2 执行的活动 一、概念 1.Agile Development。 2.敏捷开发的总体目标是通过“尽可能早地、持续地对有价…

计算机网络:CSMA/CA协议

计算机网络&#xff1a;CSMA/CA协议 CSMA/CA概述帧间间隔工作原理退避算法虚拟载波监听 CSMA/CA概述 讲解CSMA/CA之前&#xff0c;我们回顾一下CSMA/CD的三个特性&#xff1a; 多址接入MA&#xff1a;多个主机连接在一条总线上&#xff0c;竞争使用总线 载波监听CS&#xff1a…

web网站搭建实验

综合练习&#xff1a;请给openlab搭建web网站 网站需求&#xff1a; 1.基于域名www.openlab.com可以访问网站内容为 welcome to openlab!!! 2.给该公司创建三个子界面分别显示学生信息&#xff0c;教学资料 和缴费网站&#xff0c;基于&#xff0c;www.openlab.com/data网站…

麦克斯韦方程简单理解波粒二象性粒子退相干(Quantum Decoherence):微观的动态,宏观的静态量子

目录 麦克斯韦方程简单理解 波粒二象性 粒子退相干(Quantum Decoherence):微观的动态,宏观的静

X-314智能合约:金融创新的强大引擎

&#x1f4a5;火爆到烫手的X-314智能合约&#x1f525; X-314智能合约是基于以太坊区块链开发的&#xff0c;具有高度可定制性和灵活性。 ave开单独板块&#xff1b;详细资料已经准备好&#xff1b;对web3感兴趣的大佬货&#xff1b;多交流多指导&#x1f91d; ​X-314智能合…

JUC(java.util.concurrent) 的常见类

Callable 接口 Callable 的用法 Callable 是一个 interface&#xff08;类似之前的 Runnable&#xff0c;用来描述一个任务&#xff0c;但是没有返回值&#xff09;也是描述一个任务的&#xff0c;有返回值。方便程序猿借助多线程的方式计算结果. 例如&#xff1a;创建线程…