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;
    }
};

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

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

相关文章

Spring MVC和Spring Boot

上节已经提到过请求&#xff0c;这次梳理响应。 响应 响应基本上都要被Controller所托管&#xff0c;告诉Spring帮我们管理这个代码&#xff0c;我们在后面需要访问时&#xff0c;才可以进行访问&#xff0c;否则将会报错。并且其是由RestController分离出来的&#xff0c;Re…

免杀技术之白加黑的攻击防御

一、介绍 1. 什么是白加黑 通俗的讲白加黑中的白就是指被杀软列入到可信任列表中的文件。比如说微软自带的系统文件或者一些有有效证书签名的文件,什么是微软文件&#xff0c;或者什么是有效签名文件在后面我们会提到他的辨别方法。黑就是指我们自己的文件&#xff0c;没有有…

allegro输出正反面bom

不是前面两条命令&#xff0c;而是component report

Scrapy

【 一 】Scrapy介绍 【0】前言 Scrapy知识预备 ​ 爬虫毕竟是在网页里面抓取数据的,因此前端那些东西没学过也要稍微懂点。HTML、CSS简单的语法,Xpath、正则表达式等等,需要有一些简单的基础。 ​ Scrapy一个开源和协作的框架,其最初是为了页面抓取(更确切来说,网络抓…

Day26: Redis入门、开发点赞功能、开发我收到的赞的功能、重构点赞功能、开发关注、取消关注、开发关注列表、粉丝列表、重构登录功能

Redis入门 简介 Redis是NoSQL数据库&#xff08;Not only SQL&#xff09;值支持多种数据结构&#xff08;key都是string&#xff09;&#xff1a;字符串、哈希、列表、集合、有序集合把数据存在内存中&#xff0c;速度惊人&#xff1b;同时也可以讲数据快照&#xff08;数据…

(一)JVM实战——jvm的组成部分详解

前言 本节内容是关于java虚拟机JVM组成部分的介绍&#xff0c;通过其组成架构图了解JVM的主要组成部分。 正文 ClassFile&#xff1a;字节码文件 - javac&#xff1a;javac前端编译器将源代码编译成符合jvm规范的.class文件&#xff0c;即字节码文件 - class文件的结构组成&a…

【智能算法】指数分布优化算法(EDO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2023年&#xff0c;M Abdel-Basset等人受到指数分布理论启发&#xff0c;提出了指数分布优化算法&#xff08;Exponential Distribution Optimizer, EDO&#xff09;。 2.算法原理 2.1算法思想 ED…

mac系统镜像源管理之nrm的安装与使用

之前有介绍过&#xff1a;pnpm安装和使用&#xff0c;nvm安装及使用&#xff0c;在前端开发中其实还有一个工具也会偶尔用到&#xff0c;那就是nrm&#xff0c;本文就详解介绍一下这个工具&#xff0c;非常的简单且好用&#xff5e; 文章目录 1、什么是nrm&#xff1f;2、安装3…

CPU资源控制

一、CPU资源控制定义 cgroups&#xff08;control groups&#xff09;是一个非常强大的linux内核工具&#xff0c;他不仅可以限制被namespace隔离起来的资源&#xff0c; 还可以为资源设置权重、计算使用量、操控进程启停等等。 所以cgroups&#xff08;control groups&#xf…

【IC设计】奇数分频与偶数分频 电路设计(含讲解、RTL代码、Testbench代码)

文章目录 原理分析实现和仿真偶数分频的电路RTL代码偶数分频的电路Testbench代码偶数分频的电路仿真波形占空比为50%的三分频电路RTL代码占空比为50%的三分频电路Testbench代码占空比为50%的三分频电路仿真波形 参考资料 原理分析 分频电路是将给定clk时钟信号频率降低为div_c…

Springboot 整合 Quartz框架做定时任务

在Spring Boot中整合Quartz&#xff0c;可以实现定时任务调度的功能 1、首先&#xff0c;在pom.xml文件中添加Quartz和Spring Boot Starter Quartz的依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-bo…

基于MNIST的手写数字识别

上次我们基于CIFAR-10训练一个图像分类器&#xff0c;梳理了一下训练模型的全过程&#xff0c;并且对卷积神经网络有了一定的理解&#xff0c;我们再在GPU上搭建一个手写的数字识别cnn网络&#xff0c;加深巩固一下 步骤 加载数据集定义神经网络定义损失函数训练网络测试网络 …

AI绘画怎么用涂抹消除处理图片?

AI绘画软件中的涂抹消除功能通常用于处理图片&#xff0c;以去除不需要的部分或进行细节调整。不同的AI绘画软件可能具有不同的界面和功能设置&#xff0c;因此具体的操作步骤可能会有所不同。那么AI绘画一般怎么用涂抹消除处理图片? 该功能主打“一键消除&#xff0c;不留痕迹…

【MCU】栈溢出问题

项目场景&#xff1a; 硬件&#xff1a;STM32F407&#xff0c;操作系统&#xff1a;rt_thread master分支 问题描述 问题栈溢出 id 499 ide 00 rtr 00 len 8 9 Function[rt_completion_wait] shall not be used in ISR (0) assertion failed at function:rt_completion_wait,…

由于磁盘空间不够导致服务无法访问的情况

昨天服务出现了一些“小状况”&#xff0c;这里做下记录&#xff0c;为了以后类似的问题&#xff0c;可以作为参考。 具体情况是&#xff0c;如下&#xff1a; 本来一直访问都好好的服务突然间访问不到了&#xff0c;首先确定了下服务器上的 docker 服务是否正常运行。确认正…

粒子群算法与优化储能策略python实践

粒子群优化算法&#xff08;Particle Swarm Optimization&#xff0c;简称PSO&#xff09;, 是1995年J. Kennedy博士和R. C. Eberhart博士一起提出的&#xff0c;它是源于对鸟群捕食行为的研究。粒子群优化算法的基本核心是利用群体中的个体对信息的共享从而使得整个群体的运动…

【办公类-26-01】20240422 UIBOT网络教研(自动登录并退出多个账号,半自动半人工)

作品展示&#xff1a; 背景需求&#xff1a; 每学期有多次网络教研 因为我有历任搭档的进修编号和登录密码&#xff0c; 所以每次学习时&#xff0c;我会把历任搭档的任务也批量完成。 但是每次登录都要从EXCEL里复制一位老师的“进修编号”“密码”&#xff0c;还要点击多次…

快速回复app是什么样

在电商领域&#xff0c;掌握一些必备的软件工具是提高工作效率、优化运营流程以及提升用户体验的关键。本文将为您介绍做电商必备的几个软件&#xff0c;帮助您更好地开展电商业务。 ​ 快速回复APP&#xff1a;重新定义沟通效率 在快节奏的现代社会中&#xff0c;人们对于沟通…

53.基于微信小程序与SpringBoot的戏曲文化系统设计与实现(项目 + 论文)

项目介绍 本站采用SpringBoot Vue框架&#xff0c;MYSQL数据库设计开发&#xff0c;充分保证系统的稳定性。系统具有界面清晰、操作简单&#xff0c;功能齐全的特点&#xff0c;使得基于SpringBoot Vue技术的戏曲文化系统设计与实现管理工作系统化、规范化。 技术选型 后端:…

Aigtek功率放大器的工作特点有哪些方面

功率放大器是电子设备中常见的元器件&#xff0c;用于将输入信号的功率增加到所需的输出功率水平。它在各种应用中发挥着重要作用&#xff0c;如音频放大、射频信号处理、通信系统等。功率放大器具有以下几个工作特点&#xff1a; 放大功能&#xff1a;功率放大器主要的工作特点…