【leetcode】将x减到0的最小操作数/水果成篮/找到字符串中所有字母异位词{史上最容易懂的解析}

news2024/11/19 15:15:22

文章目录

  • 1.将x减到0的最小操作数
  • 2.水果成篮
  • 3.找到字符串中所有字母异位词

1.将x减到0的最小操作数

在这里插入图片描述
在这里插入图片描述

分析题目

x不断地减去数组两端的值 看能否减到0;是不是就是在问:nums数组中存不存在【左端+右端】组成的连续区间,区间上数的和为x 继续分析 ==》 是不是就是在问:nums数组中存不存在内部的一段连续区间,区间上的数的和为sum(nums) - x 很明显,这是个经过分析的【滑动窗口】问题

代码

class Solution
{
public:
    int minOperations(vector<int> &nums, int x)
    {
        int sum = 0;
        for (int a : nums)
            sum += a;
        int target = sum - x;

        //x比sum大 sum中就不会存在几个数的和==x
        if (target < 0)
            return -1;

        int ret = -1;
        for (int left = 0, right = 0, tmp = 0; right < nums.size(); right++)
        {
            tmp += nums[right];     
            while (tmp > target)     
                tmp -= nums[left++]; 
            if (tmp == target)       
                ret = max(ret, right - left + 1);
        }
        
        if (ret == -1)
            return ret;
        else
            return nums.size() - ret;
    }
};

2.水果成篮

在这里插入图片描述
在这里插入图片描述

分析

依旧是滑动窗口,一个区间,该区间内水果种类不能超2,超2就将下一个元素作为区间的起始位置

代码

class Solution
{
public:
    int totalFruit(vector<int> &f)
    {
        // i是树的下标 fruits[i]是水果的种类编号 fruits[i]: 0~100000
        int hash[100001] = {0}; // 以水果的种类编号作hash的下标 对应值记录该种水果出现次数

        int ret = 0;
        for (int left = 0, right = 0, kinds = 0; right < f.size(); right++)
        {
            // 当前遍历的该水果在篮子里的次数是0 种类++
            if (hash[f[right]] == 0)
                kinds++;

            // 当前遍历的该水果可以出现在篮子里
            hash[f[right]]++;

            while (kinds > 2)
            {
                // left作起始位置的这个区间已达最大长度 继续遍历 将下一个元素作为区间的起始位置
                hash[f[left]]--;        // 出窗口 水果次数--
                if (hash[f[left]] == 0) // 如果拿出窗口的水果在原来的篮子里是独苗 种类也--
                    kinds--;
                left++; // 继续下一个元素作为区间的起始位置
            }
            ret = max(ret, right - left + 1);
        }
        return ret;
    }
};

cpp_stl容器unordered_map

class Solution
{
public:
    int totalFruit(vector<int> &f)
    {
        unordered_map<int, int> hash; 

        int ret = 0;
        for (int left = 0, right = 0; right < f.size(); right++)
        {
            hash[f[right]]++;      
            while (hash.size() > 2) 
            {
                hash[f[left]]--;
                if (hash[f[left]] == 0)
                    hash.erase(f[left]);
                left++;
            }
            ret = max(ret, right - left + 1);
        }
        return ret;
    }
};

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

在这里插入图片描述

在这里插入图片描述

滑动窗口的分类

  1. 区间长度固定如本题
  2. 左指针疯狂右移 right不动
  3. 右指针疯狂右移 left不动

总体思路:这道题【维护窗口的时机】发生在窗口的长度超过了p的长度,保证窗口的长度只能不大于p的长度

遍历母串,遍历到who,不管符不符合条件,who就先进窗口,如果who是一个【有效字符】即【可以作为异位词的字符】即【在p中出现且次数不超过在p中出现的字符】,接着上一句,如果who是一个【有效字符】,那么有效字符个数validChar++; 经过不断遍历,如果窗口的长度已经大于p的长度,窗口就要右移了,即left++; 并且left在窗口中的次数也要winHash[out - 'a']--; 需要注意的是,如果移出去的left,他对应的值在窗口中出现的次数大于在p中出现的次数,left移出后,有效字符个数不变,left出去正是我们想要的,这个操作表明窗口中少了一个不该出现的字符,这使得区间中的字符越来越接近我们想要的字符组合即异位词。上述操作保证了窗口的长度只能不大于p的长度。接着再判断,如果此时窗口中的有效字符个数 == p的长度,表示我们找了“异位词”。如果此时validChar != pLen 表示: 虽然窗口的长度到达了pLen,但是窗口中的字符并不是全部有效,还要继续添加新元素,来满足:窗口的长度为pLen且均为有效字符。

代码 + 史上最全解析

class Solution
{
public:
    vector<int> findAnagrams(string s, string p)
    {
        vector<int> ret;
        int sLen = s.size(), pLen = p.size(), validChar;

        // 母串长度比子串长度还小 直接返回
        if (sLen < pLen)
            return ret;

        // p字符串有哪些字符 分别出现了多少次
        // phash中值不为0的下标代表有哪些字符 值就是它出现的次数
        int pHash[26] = {0};
        for (auto ch : p)
            pHash[ch - 'a']++;

        // 记录窗口中有哪些字符以及对应出现的次数
        int winHash[26] = {0};

        // 要理解这种写法 要理解两个关键字
        // 1. winHash  :窗口中有哪些字符以及对应出现的次数
        // 2. validChar:窗口中有效字符的个数
        for (int left = 0, right = 0, validChar = 0; right < s.size(); right++)
        {
            // in:即将进入窗口的字符
            char in = s[right];

            // 遍历到in了 in默认进窗口 用【in在窗口中的次数++】来表征in进窗口了
            // 如果此时窗口中in的次数大于p中in的次数 那么in是作为一个无效字符进的窗口 有效字符个数不变
            // 如果此时窗口中in的次数不大于p中in的次数 表明in此时在窗口中是一个有效字符 有效字符个数++
            if (++winHash[in - 'a'] <= pHash[in - 'a'])
                validChar++;

            // 窗口的长度已经大于子串了
            if (right - left + 1 > pLen)
            {
                char out = s[left++];

                // out在窗口中出现的次数 <= out在p中出现的次数 有效字符个数--
                // 反向理解
                // 如果out在窗口中出现的次数 > out在p中出现的次数
                // out移出后 有效字符个数不变 out出去正是我们想要的 窗口中少了一个不该出现的字符
                // 这使得区间中的字符越来越接近我们想要的字符组合了即异位词
                if (winHash[out - 'a']-- <= pHash[out - 'a'])
                    validChar--;
            }

            // 前面两个if保证窗口的窗口不会超过p的长度
            // 如果此时validChar == pLen即窗口中的有效字符个数等于p的长度 表示我们找了“异位词”
            // 如果此时validChar != pLen 表示: 虽然窗口的长度到达了pLen 但是窗口中的字符并不是全部有效
            // 还要继续添加新元素 来满足:窗口的长度为pLen且均为有效字符
            if (validChar == pLen)
                ret.push_back(left);
        }
        return ret;
    }
};

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

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

相关文章

VSCode 插件 Template String Converter

1. 插件介绍 点击安装 Template String Converter 插件 Template String Converter 翻译后&#xff1a;模板字符串转换器。 插件作用&#xff1a;当 JavaScript 字符串中键入 ${ 时自动将引号转为反引号&#xff0c;当删除 ${ 时自动将反引号转为普通引号 功能示例&#xff…

Verilator入门11:仿真玄铁测试case

这一节&#xff0c;介绍下如何使用verilator仿真玄铁&#xff0c;之前有相关介绍&#xff0c;本节将进一步介绍下玄铁具体case的仿真&#xff0c;首先需要clone玄铁代码&#xff1a; git clone https://github.com/kknet/openc910.git 同时下载交叉编译工具&#xff0c;网站地…

YOLOv8 UI界面设计+热力图显示

进入可视化设计界面&#xff0c;设计UI pyside6-designer 设计好UI保存&#xff0c;然后通过以下命令将ui文件保存为py pyside6-uic myui.ui > myui.py 通过以下命令将资源文件qrc保存为py pyside6-rcc my_rc.qrc > my_rc.py 写主窗口函数实现功能... 项目基于yol…

vue 数据埋点

最近菜鸟做项目&#xff0c;需要做简单的数据埋点&#xff0c;不是企业级的&#xff0c;反正看渡一的视频&#xff0c;企业级特别复杂&#xff0c;包括但不限于&#xff1a;错误收集、点击地方、用户行为…… 菜鸟的需求就是简单收集一下用户的ip、地址、每个界面的访问时间&a…

Ubuntu20.04使用Neo4j导入CSV数据可视化知识图谱

1.安装JDK&#xff08; Ubuntu20.04 JDK11&#xff09; sudo apt-get install openjdk-11-jdk -y java -version which java ls -l /usr/bin/java ls -l /etc/alternatives/java ls -l /usr/lib/jvm/java-11-openjdk-amd64/bin/java确认安装路径为/usr/lib/jvm/java-11-openjd…

【VUE+ElementUI】el-table表格固定列el-table__fixed导致滚动条无法拖动

【VUEElementUI】el-table表格固定列el-table__fixed导致滚动条无法拖动 背景 当设置了几个固定列之后&#xff0c;表格无数据时&#xff0c;点击左侧滚动条却被遮挡&#xff0c;原因是el-table__fixed过高导致的 解决 在index.scss中直接加入以下代码即可 /* 设置默认高…

最优算法100例之26-翻转单词顺序

专栏主页&#xff1a;计算机专业基础知识总结&#xff08;适用于期末复习考研刷题求职面试&#xff09;系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 牛客最近来了一个新员工Fish&#xff0c;每天早晨总是会拿着一本英文杂志&#xff0c;写些句…

【北京迅为】《iTOP-3588开发板系统编程手册》第1章 系统编程初探

RK3588是一款低功耗、高性能的处理器&#xff0c;适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用&#xff0c;RK3588支持8K视频编解码&#xff0c;内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP&…

基于单片机的超声波测距仪设计_kaic

摘 要 如今社会持续深化转型&#xff0c;在人工智能领域&#xff0c;传感器采集外部数据&#xff0c;经过处理器对数 据运算和处理&#xff0c;从而实现相应的功能。比如自动驾驶技术中&#xff0c;超声波传感器应用广泛&#xff0c; 超声波是一种频率在 20khz 以上的声波&…

STM32-04基于HAL库(CubeMX+MDK+Proteus)中断案例(按键中断扫描)

文章目录 一、功能需求分析二、Proteus绘制电路原理图三、STMCubeMX 配置引脚及模式&#xff0c;生成代码四、MDK打开生成项目&#xff0c;编写HAL库的按键检测代码五、运行仿真程序&#xff0c;调试代码 一、功能需求分析 在完成GPIO输入输出案例之后&#xff0c;开始新的功能…

如何防止IP泄露,安全匿名上网?

当互联网成为每个家庭的重要组成部分后&#xff0c;IP地址就成了你的虚拟地址。您的请求从该地址开始&#xff0c;然后 Internet 将消息发送回该地址。那么&#xff0c;您担心您的地址被泄露吗&#xff1f; 对于安全意识高或者某些业务需求的用户&#xff0c;如果您正在寻找保护…

用户认证安全性测试

用户认证安全性测试 认证与会话管理认证--Authentication01 常见认证方式02 session认证Session Fixation攻击Session保持攻击 03 Token认证多因素认证session和token区别 04 暴力破解密码的那些事密码设置推荐策略 会话--Authorization 权限控制权限管理方式垂直权限管理水平权…

redis 集群 (主从复制 哨兵模式 cluster)

目录 一 主从复制 &#xff08;一&#xff09;相关理论 1&#xff0c;主从复制定义 2&#xff0c;主从复制的作用 3&#xff0c;主从复制架构图 4 sync 同步过程 5&#xff0c;主从复制流程 &#xff08;二&#xff09; 实验模拟 1&#xff0c; 实验环境 2, 修…

【ArduinoQuartus】在小脚丫STEP CYC10上安装PulseRain Reindeer并在软核上运行基础功能

【Arduino&Quartus】在小脚丫STEP CYC10上安装PulseRain Reindeer并在软核上运行基础功能 一、将Reindeer软核下载到STEP CYC10&#xff08;一&#xff09;下载PulseRain Reindeer软核&#xff08;二&#xff09;配置Reindeer软核到开发板1.将sof文件转换为jic文件2.将jic文…

【动态】江西省小型水库安全监测能力提升试点项目通过验收

近日&#xff0c;由北京国信华源科技有限公司和长江勘测规划设计研究有限责任公司联合承建的江西省小型水库安全监测能力提升试点项目圆满通过验收。 在项目业主单位的组织下&#xff0c;省项目部、特邀专家、县水利局二级项目部以及项目设计、监理、承建等单位的代表组成验收工…

OpenHarmony实战:小型系统器件驱动移植

本章节讲解如何移植各类器件驱动。 LCD驱动移植 移植LCD驱动的主要工作是编写一个驱动&#xff0c;在驱动中生成模型的实例&#xff0c;并完成注册。 这些LCD的驱动被放置在源码目录//drivers/hdf_core/framework/model/display/driver/panel中。 创建Panel驱动 创建HDF驱动…

Nginx从安装到高可用实用教程!

一、Nginx安装 1、去官网http://nginx.org/下载对应的nginx包&#xff0c;推荐使用稳定版本 2、上传nginx到linux系统 3、安装依赖环境 (1)安装gcc环境 yum install gcc-c(2)安装PCRE库&#xff0c;用于解析正则表达式 yum install -y pcre pcre-devel(3)zlib压缩和解压缩…

C++输出格式控制

setprecision(n)可控制输出流显示浮点数的数字个数。C默认的流输出数值有效位是6&#xff0c;所以不管数据是多少&#xff0c;都只输出六位。如果setprecision(n)与setiosflags(ios::fixed)或者setiosflags(ios_base::fixed)合用&#xff0c;可以控制小数点右边的数字个数。set…

中间件复习之-RPC框架

什么是RPC框架&#xff1f; RPC(Remote Procedure Call):远程过程调用。当多个应用部署在多个服务器上时&#xff0c;由于他们不在一个内存空间上&#xff0c;因此需要网络来进行通信&#xff0c;而RPC允许它像调用本地方法一样调用远程服务。 RPC原理 服务消费方通过RPC客户…

UE5 C++ LevelSequence

前言 最近在用UE C做一些功能&#xff0c;用到了Level Sequence功能&#xff0c;但是看了下UE官方论坛包括一些文章基本没有关于C 处理Level Sequence 这块内容&#xff0c;有的也是一些修改或者源码原理的一些内容分析&#xff0c;接下来我就把我新建Sequence包括一些库的调用…