算法——滑动窗口(day8)

news2024/9/21 20:48:30

30.串联所有单词的子串 

30. 串联所有单词的子串 - 力扣(LeetCode) 

必看!!!本题是我们上次写的438.异位词的进阶版,可参考本篇文章:算法——滑动窗口(day7)-CSDN博客来帮助理解。

题目解析:

这里我就默认大家都已经看过我们上一篇题解的思路了~ 

本道题我们可以通过题意:words数组内所有字符串长度相同的特性对问题进行转化~

例如,我们可以把words数组内的其中一个字符串想象成字符a,另一个字符串想象成字符b。然后也对字符串s中进行成队字符串转化(这里是长度为3的字符串转化为1字符)。双方转化完之后我们就可以发现这跟之前的求异位词那道题已经没有什么区别了~

算法解析:

这里我们再来补充一下细节问题:比如right遍历移动的时候应该是跨words数组中的字符串长度进行移动,因为我们把一段子串想象成一个字符,所以哈希表录入的时候都是已子串录入的,那么我们就不能单纯让right一个字符一个字符遍历,而是一段子串一段子串遍历。left也同样如果。不过在遍历完毕后还需要注意,还有绿色线,黄色线这种划分情况,至于黑色线只不过比蓝色线少了一个字符串,所以没必要划分了~

滑动流程图:

其实只要能把问题转化为我们上一题的思路剩下的就简单了,基本思路是一样的,后面再考虑一下两个哈希表的字符串录入,双指针的移动距离,考虑到所有情况的发生就好了。

代码:

 

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        //记录字符串数组words的数据
        unordered_map<string, int>hash2;
        for (auto& ch : words)
        {
            hash2[ch]++;
        }
        //字符串数组中每个字符串的长度
        int m = words[0].size();
        //字符串数组中数组的个数
        int n = words.size();
        //记录结果
        vector<int> ret;
        int k = 0;
        //多层循环做到不遗漏
        while (k < m)
        {
            //在每一层新的循环中都有特定记录字符串s的哈希表
            unordered_map<string, int>hash1;
            for (int left = k, right = k, count = 0; right + m <= s.size(); right += m)
            {
                //获取特定长度的字符串录入hash1中
                string a = s.substr(right, m);
                //正常情况下,窗口长度短时扩充窗口
                //先录入所选子串数据
                hash1[a]++;
                //判定录入的数据是否为可以抵消hash2中对应的有效字符串
                if (hash1[a] <= hash2[a])
                {
                    count++;
                }
                //扩充完发现仍过短就跳到下一循环继续扩充
                //当窗口长度过长时候,开始缩小窗口
                if (right - left + 1 > m * n)
                {
                    //获取特定长度的字符串
                    string b = s.substr(left, m);
                    //删减对应字符串个数
                    hash1[b]--;
                    //如果删完后发现缺少了抵消hash2中对应子串可能性
                    if (hash1[b] < hash2[b])
                    {
                        //有效字符串减一
                        count--;
                    }
                    left += m;
                }
                //当有效字符串个数完全可以抵消时
                if (count == n)
                {
                    //录入结果
                    ret.push_back(left);
                }
            }
            //开始下一轮的循环
            k++;
        }

        return ret;
    }
};

 

76.最小覆盖子串

76. 最小覆盖子串 - 力扣(LeetCode)

题目解析:

这道题依然可以利用两个哈希表进行辅助,不过与其他题不同的是本题只要划分好的s内至少有t对应的字符就行了, 多了也没事。

对暴力进行分析,如果已经找到满足条件的子串那么left在进入下一轮的遍历时right需要复位吗?————不需要假设【left,right】为目标子串的范围,left继续前进只有2种可能

  • 要么缩小窗口后仍满足条件,这时候只需要让right呆在原地,然后记录满足条件的新子串范围【left,right】即可。
  • 要么不符合所需条件,就让right继续前进直到找到所需字符。

所以不管怎么样right都是不用复位的,而这也引出了我们的滑动窗口~

算法解析:

滑动窗口流程图:

之所以找字符种类而不是个数是因为本题只要满足t中所含字符即可,个数超出也无大碍。那我们就以hash2中的个数为基准,假设hash2中a有2个,那么只有hash1中a的个数也达2个跟hash2相等那才能算是一个有效种类。在未达到数量标准之前都不算为有效种类~

基本思路为:

  • 进窗口:进之前先录入数据到hash1中,然后判断两表中该字符个数是否相等(若相等,count++)
  • 判断,这里是以判断count与m是否相等,若相等则说明找到子串,更新结果,然后不断出窗口直到count不等于m为止(在这个过程可以找出更多子串)
  • 出窗口:出之前先判断两表中该字符个数是否相等(若相等,则说明删减后无法匹配,则count--),然后删减数据

代码:

class Solution {
public:
    string minWindow(string s, string t) {
        //记录字符串s的数据
        unordered_map<int, int>hash1;
        //记录字符串t的数据
        unordered_map<int, int>hash2;

        for (auto ch : t)
        {
            hash2[ch - 'a']++;
        }
        int count = 0;
        int len = INT_MAX;
        int begin = -1;
        //计算t中字符的种类
        int m = hash2.size();
        for (int left = 0, right = 0; right < s.size(); right++)
        {
            //扩充窗口
            //录入数据
            hash1[s[right] - 'a']++;
            //录入完如果两表字符数量相等,则说明count可+1
            if (hash1[s[right] - 'a'] == hash2[s[right] - 'a'])
            {
                count++;
            }
            //在扩充窗口的过程中如果已经找到可匹配的子串
            while (count == m)
            {
                //记录所找子串长度以及起始位置
                if (right - left + 1 < len)
                {
                    len = right - left + 1;
                    begin = left;
                }
                //判断在缩小窗口之前两表中字符个数是否相等
                if (hash1[s[left] - 'a'] == hash2[s[left] - 'a'])
                {
                    //若相等则说明该字符出窗口后无法与hash2对应字符匹配
                    count--;
                }
                //移除该字符
                hash1[s[left] - 'a']--;
                //缩小窗口
                left++;

            }
        }
        //未找到目的子串
        if (begin == -1)
        {
            return "";
        }
        else
        {
            return s.substr(begin, len);
        }
    }
};

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

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

相关文章

c++笔记2

目录 2.2 栈底&#xff08;bottom&#xff09; } 大数乘大数 节点&#xff1a;包含一个数据元素及若干指向子树分支的信息 。 节点的度&#xff1a;一个节点拥有子树的数目称为节点的度 。 叶子节点&#xff1a;也称为终端节点&#xff0c;没有子树的节点或者度为零的节点…

vue3+openLayers触摸事件显示弹窗

<template><!--地图--><div class"distributeMap" id"distributeMap"></div><!--弹窗--><section ref"popup" id"popupDiv" class"popup">{{ state.popupParams.name }}</section&g…

OpenGauss和GaussDB有何不同

OpenGauss和GaussDB是两个不同的数据库产品&#xff0c;它们都具有高性能、高可靠性和高可扩展性等优点&#xff0c;但是它们之间也有一些区别和相似之处。了解它们之间的关系、区别、建议、适用场景和如何学习&#xff0c;对于提高技能和保持行业敏感性非常重要。本文将深入探…

电脑ip地址怎么改?修改技巧大放送!

在现代网络环境中&#xff0c;IP地址的设置对于连接互联网和局域网至关重要。无论是因为网络配置的需求&#xff0c;还是出于隐私和安全考虑&#xff0c;学会更改电脑的IP地址是一项有用的技能。本文将介绍电脑ip地址怎么改的3种方法&#xff0c;帮助您根据不同需求灵活调整网络…

Go并发GMP调度模型

如何知道一个对象是分配在栈上还是堆上&#xff1f; Go和C不同&#xff0c;Go的逃逸分析是在编译器完成的&#xff1b;go局部变量会进行逃逸分析。如果变量离开作用域后没有被引用&#xff0c;则优先分配到栈上&#xff0c;否则分配到堆上。那么如何判断是否发生了逃逸呢&#…

VMWare 16 安装

1、下载地址 VMware-workstation-full-16.2.4-20089737 2、激活码 VM16&#xff1a;ZF3R0-FHED2-M80TY-8QYGC-NPKYF 3、安装步骤 修改一下【安装位置】&#xff0c;将【增强型键盘驱动程序(需要重新引导以使用此功能()此功能要求主机驱动器上具有 10MB 空间。】【将 wMware…

【LLM】-07-提示工程-聊天机器人

目录 1、给定身份 1.1、基础代码 1.2、聊天机器人 2、构建上下文 3、订餐机器人 3.1、窗口可视化 3.2、构建机器人 3.3、创建JSON摘要 利用会话形式&#xff0c;与具有个性化特性&#xff08;或专门为特定任务或行为设计&#xff09;的聊天机器人进行深度对话。 在 Ch…

钉钉 ai卡片 stream模式联调

sdk连接 新建卡片模板下载node.js sdkconfig.json 配置应用信息 启动项目npm i npm run build npm run start连接成功 获取卡片回调 注册卡片回调事件调用https://api.dingtalk.com/v1.0/card/instances 创建卡片实例&#xff0c;返回实例Id //参数结构 {"cardTempla…

同花顺股票数据逆向:Cookie加密和Hook注入

&#x1f50d; 思路与步骤详解 &#x1f310; 抓包解析接口 首先&#xff0c;我们使用抓包工具对同花顺的股票数据接口进行分析&#xff0c;发现其中的Cookie参数经过了加密处理。 接下来&#xff0c;我们需要深入挖掘这些加密参数的生成位置。 &#x1f6e0; hook注入 对于…

信号的运算

信号实现运算&#xff0c;首先要明确&#xff0c;电路此时为负反馈电路&#xff0c;当处于深度负反馈时&#xff0c;可直接使用虚短虚断。负反馈相关内容可见&#xff1a;放大电路中的反馈_基极反馈-CSDN博客https://blog.csdn.net/qq_63796876/article/details/140438759 一、…

【深度学习总结】基于U-Mamba使用nnUNetv2处理BraTS挑战赛数据

基于U-Mamba使用nnUNetv2处理BraTS挑战赛数据 【深度学习总结】基于U-Mamba使用nnUNetv2处理BraTS挑战赛数据U-Mamba介绍数据集下载环境准备数据集准备运行其他2D网络结构UMambaBot的模型结构UMambaEnc的模型结构 【深度学习总结】基于U-Mamba使用nnUNetv2处理BraTS挑战赛数据 …

matlab仿真 数字基带传输(下)

&#xff08;内容源自详解MATLAB&#xff0f;SIMULINK 通信系统建模与仿真 刘学勇编著第六章内容&#xff0c;有兴趣的读者请阅读原书&#xff09; clear all Fd1;%符号采样频率 Fs10;%滤波器采样频率 r0.2;%滤波器滚降系数 delay4;%滤波器时延 [num,den]rcosine(Fd,Fs,defau…

使用LLaMA-Factory对Llama3-8B-Chinese-Chat进行微调

文章目录 模型及数据&#xff1a;模型下载数据 LLaMA-Factory启动拉取代码启动webui 模型训练数据导入数据预览设置模型路径配置参数及参数的保存开始训练 过程观察加载模型、对话模型导出、再次加载 模型及数据&#xff1a; 模型下载 使用基于中文数据训练过的 LLaMA3 8B 模…

Java基本数据类型与String类型的转换

目录 基本数据类型和Strng类型的转换 第一种方法 第二种方法 将字符串转成字符 注意事项 本章练习题 题1 题2 基本数据类型和Strng类型的转换 第一种方法 使用号和" "即可完成转换 第二种方法 第二种方法是通过基本类型的包装类调用parsexx方法 将字符…

计算机视觉与图像分类:技术原理、应用与发展前景

引言 随着科技的不断进步&#xff0c;计算机视觉逐渐成为了人工智能领域的重要分支之一。计算机视觉旨在让计算机具备“看懂”图像和视频的能力&#xff0c;从而理解和分析视觉信息。作为计算机视觉中的一个关键任务&#xff0c;图像分类涉及将输入的图像归类到预定义的类别中&…

Ubuntu20.04安装Elasticsearch

简介 ELK&#xff08;Elasticsearch, Logstash, Kibana&#xff09;是一套开源的日志管理和分析工具&#xff0c;用于收集、存储、分析和可视化日志数据。以下是如何在Ubuntu服务器上安装和配置ELK堆栈以便发送和分析日志信息的步骤。 安装Elasticsearch 首先&#xff0c;安…

使用 vSphere vCenter 管理 ESXi

使用 vSphere vCenter 管理 ESXi 1、新建数据中心 在 vSphere Client 中&#xff0c;左上角图标&#xff0c;进入 “清单”&#xff0c;鼠标右键名称&#xff0c;新建数据中心。 输入数据中心名称&#xff0c;我这里直接使用默认值&#xff0c;点击确定。 2、往数据中心中添加…

html+css 边框滑动按钮效果

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽效果&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 文…

QT:控件圆角设置、固定窗口大小

实现控件圆角度设置//使用的是setStyleSheet方法 //改变的控件是QTextEdit&#xff0c;如果你想改变其他控件&#xff0c;将QTextEdit进行更换 this->setStyleSheet("QTextEdit{background-color:#FFFFFF;border-top-left-radius:15px;border-top-right-radius:15px;bo…

Qt多语言功能实现

本文介绍Qt多语言功能实现。 应用程序多语言支持是常用功能&#xff0c;比如产品需要出口到不同语种的国家。采用Qt的多语言支持工具可以方便实现应用程序的多语言功能。本文以中英文语言切换为例&#xff0c;简要介绍Qt的多语言功能实现。 1.界面设计 界面设计需要考虑使用…