【优选算法】(第八篇)

目录

串联所有单词的⼦串(hard)

题目解析

讲解算法原理

编写代码

最⼩覆盖⼦串(hard)

题目解析

讲解算法原理

编写代码


串联所有单词的⼦串(hard)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

给定⼀个字符串s和⼀个字符串数组words。words中所有字符串⻓度相同。
s中的串联⼦串是指⼀个包含words中所有字符串以任意顺序排列连接起来的⼦串。
◦ 例如,如果words=[)ab),)cd),)ef)],那
么)abcdef),)abefcd),)cdabef),)cdefab),)efabcd),和)efcdab)都是串联⼦串。)acdbef)不是串联⼦串,因为他不是任何words排列的连接。
返回所有串联字串在s中的开始索引。你可以以任意顺序返回答案。
⽰例1:
输⼊:s=)barfoothefoobarman),words=[)foo),)bar)]输出:[0,9]
解释:因为words.length==2同时words[i].length==3,连接的⼦字符串的⻓度必须为6。⼦串)barfoo)开始位置是0。它是words中以[)bar),)foo)]顺序排列的连接。
⼦串)foobar)开始位置是9。它是words中以[)foo),)bar)]顺序排列的连接。输出顺序⽆关紧要。返回[9,0]也是可以的。
⽰例2:
输⼊:s=)wordgoodgoodgoodbestword),words=[)word),)good),)best),)word)]输出:[]
解释:因为words.length==4并且words[i].length==4,所以串联⼦串的⻓度必须为16。s中没有⼦串⻓度为16并且等于words的任何顺序排列的连接。
所以我们返回⼀个空数组。
⽰例3:
输⼊:s=)barfoofoobarthefoobarman),words=[)bar),)foo),)the)]输出:[6,9,12]
解释:因为words.length==3并且words[i].length==3,所以串联⼦串的⻓度必须为9。⼦串)foobarthe)开始位置是6。它是words中以[)foo),)bar),)the)]顺序排列的连接。⼦串)barthefoo)开始位置是9。它是words中以[)bar),)the),)foo)]顺序排列的连接。⼦串)thefoobar)开始位置是12。它是words中以[)the),)foo),)bar)]顺序排列的连接。

提⽰:
1<=s.length<=104
1<=words.length<=5000
1<=words[i].length<=30
words[i]和s由⼩写英⽂字⺟组成

讲解算法原理

解法⼀(暴⼒解法):
算法思路:
如果我们把每⼀个单词看成⼀个⼀个字⺟,问题就变成了找到「字符串中所有的字⺟异位词」。⽆⾮就是之前处理的对象是⼀个⼀个的字符,我们这⾥处理的对象是⼀个⼀个的单词。

编写代码

c++算法代码:

class Solution
{
public:vector<int> findSubstring(string s, vector<string>& words) {vector<int> ret;unordered_map<string, int> hash1; // 保存 words ⾥⾯所有单词的频次for(auto& s : words) hash1[s]++;int len = words[0].size(), m = words.size();for(int i = 0; i < len; i++) // 执⾏ len 次{unordered_map<string, int> hash2; // 维护窗⼝内单词的频次for(int left = i, right = i, count = 0; right + len <= s.size(); 
right += len){// 进窗⼝ + 维护 countstring in = s.substr(right, len);hash2[in]++;if(hash1.count(in) && hash2[in] <= hash1[in]) count++;// 判断if(right - left + 1 > len * m){// 出窗⼝ + 维护 countstring out = s.substr(left, len);if(hash1.count(out) && hash2[out] <= hash1[out]) count--;hash2[out]--;left += len;}// 更新结果if(count == m) ret.push_back(left);}}return ret;}
};

java算法代码:

class Solution
{public List<Integer> findSubstring(String s, String[] words) {List<Integer> ret = new ArrayList<Integer>();// 保存字典中所有单词的频次Map<String, Integer> hash1 = new HashMap<String, Integer>(); for(String str : words) hash1.put(str, hash1.getOrDefault(str, 0) + 1);int len = words[0].length(), m = words.length;for(int i = 0; i < len; i++) // 执⾏次数{// 保存窗⼝内所有单词的频次Map<String, Integer> hash2 = new HashMap<String, Integer>(); for(int left = i, right = i, count = 0; right + len <= s.length(); 
right += len){// 进窗⼝ + 维护 countString in = s.substring(right, right + len);hash2.put(in, hash2.getOrDefault(in, 0) + 1);if(hash2.get(in) <= hash1.getOrDefault(in, 0)) count++; // 判断if(right - left + 1 > len * m){// 出窗⼝ + 维护 countString out = s.substring(left, left + len);if(hash2.get(out) <= hash1.getOrDefault(out, 0)) count--;hash2.put(out, hash2.get(out) - 1);left += len;}// 更新结果if(count == m) ret.add(left);}}return ret;}
}

最⼩覆盖⼦串(hard)

题目解析

1.题目链接:. - 力扣(LeetCode)

2。题目描述

给你⼀个字符串s、⼀个字符串t。返回s中涵盖t所有字符的最⼩⼦串。如果s中不存在涵盖t所有字符的⼦串,则返回空字符串""。
注意:
对于t中重复字符,我们寻找的⼦字符串中该字符数量必须不少于t中该字符数量。如果s中存在这样的⼦串,我们保证它是唯⼀的答案。
⽰例1:
输⼊:s=)ADOBECODEBANC),t=)ABC)输出:)BANC)
解释:
最⼩覆盖⼦串)BANC)包含来⾃字符串t的*A*、*B*和*C*。⽰例2:
输⼊:s=)a),t=)a)输出:)a)
解释:
整个字符串s是最⼩覆盖⼦串。⽰例3:
输⼊:s=)a),t=)aa)输出:""
解释:
t中两个字符*a*均应包含在s的⼦串中,
因此没有符合条件的⼦字符串,返回空字符串。

讲解算法原理

解法(滑动窗⼝+哈希表):
算法思路:
◦ 研究对象是连续的区间,因此可以尝试使⽤滑动窗⼝的思想来解决。
◦ 如何判断当前窗⼝内的所有字符是符合要求的呢?
我们可以使⽤两个哈希表,其中⼀个将⽬标串的信息统计起来,另⼀个哈希表动态的维护窗⼝内字符串的信息。
当动态哈希表中包含⽬标串中所有的字符,并且对应的个数都不⼩于⽬标串的哈希表中各个字符的个数,那么当前的窗⼝就是⼀种可⾏的⽅案。
算法流程:
a. 定义两个全局的哈希表: 1 号哈希表 hash1 ⽤来记录⼦串的信息, 2 号哈希表 hash2
⽤来记录⽬标串 t 的信息;
b. 实现⼀个接⼝函数,判断当前窗⼝是否满⾜要求:
i. 遍历两个哈希表中对应位置的元素:
• 如果 t 中某个字符的数量⼤于窗⼝中字符的数量,也就是 2 号哈希表某个位置⼤于
1 号哈希表。说明不匹配,返回 false ;
• 如果全都匹配,返回 true 。
主函数中:
a. 先将 t 的信息放⼊ 2 号哈希表中;
b. 初始化⼀些变量:左右指针: left = 0,right = 0 ;⽬标⼦串的⻓度: len = 
INT_MAX ;⽬标⼦串的起始位置: retleft ;(通过⽬标⼦串的起始位置和⻓度,我们就能找到结果)
c. 当 right ⼩于字符串 s 的⻓度时,⼀直下列循环:
i. 将当前遍历到的元素扔进 1 号哈希表中;
ii. 检测当前窗⼝是否满⾜条件:
• 如果满⾜条件:
◦ 判断当前窗⼝是否变⼩。如果变⼩:更新⻓度 len ,以及字符串的起始位置
retleft ;
◦ 判断完毕后,将左侧元素滑出窗⼝,顺便更新 1 号哈希表;
◦ 重复上⾯两个过程,直到窗⼝不满⾜条件;
iii. right++ ,遍历下⼀个元素;
d. 判断 len 的⻓度是否等于 INT_MAX :
i. 如果相等,说明没有匹配,返回空串;
ii. 如果不想等,说明匹配,返回 s 中从 retleft 位置往后 len ⻓度的字符串。

编写代码

c++算法代码:

class Solution
{
public:string minWindow(string s, string t) {int hash1[128] = { 0 }; // 统计字符串 t 中每⼀个字符的频次int kinds = 0; // 统计有效字符有多少种for(auto ch : t)if(hash1[ch]++ == 0) kinds++;int hash2[128] = { 0 }; // 统计窗⼝内每个字符的频次int minlen = INT_MAX, begin = -1;for(int left = 0, right = 0, count = 0; right < s.size(); right++){char in = s[right];if(++hash2[in] == hash1[in]) count++; // 进窗⼝ + 维护 countwhile(count == kinds) // 判断条件{if(right - left + 1 < minlen) // 更新结果{minlen = right - left + 1;begin = left;}char out = s[left++];if(hash2[out]-- == hash1[out]) count--; // 出窗⼝ + 维护 count }}if(begin == -1) return "";else return s.substr(begin, minlen);}
};

java算法代码:

class Solution {public String minWindow(String ss, String tt) {char[] s = ss.toCharArray();char[] t = tt.toCharArray();int[] hash1 = new int[128]; // 统计字符串 t 中每⼀个字符的频次int kinds = 0; // 统计有效字符有多少种for(char ch : t)if(hash1[ch]++ == 0) kinds++;int[] hash2 = new int[128]; // 统计窗⼝内每个字符的频次int minlen = Integer.MAX_VALUE, begin = -1;for(int left = 0, right = 0, count = 0; right < s.length; right++){char in = s[right];if(++hash2[in] == hash1[in]) count++; // 进窗⼝ + 维护 countwhile(count == kinds) // 判断条件{if(right - left + 1 < minlen) // 更新结果{minlen = right - left + 1;begin = left;}char out = s[left++];if(hash2[out]-- == hash1[out]) count--; // 出窗⼝ + 维护 count }}if(begin == -1) return new String();else return ss.substring(begin, begin + minlen);}
}

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

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

相关文章

Redis:list类型

Redis&#xff1a;list类型 list命令非阻塞LPUSHLRANGELPUSHXRPUSHRPUSHXLPOPRPOPLINDEXLINSERTLLENLREMLTRIMLSET 阻塞BLPOPBRPOP 内部编码ziplistlinkedlistquicklist 几乎每种语言都有顺序表、数组、链表这样的顺序结构&#xff0c;Redis也做出了相应的支持。 如图&#xff…

Stable Diffusion绘画 | AI 图片智能扩充,超越PS扩图的AI扩图功能(附安装包)

来到「文生图」页面&#xff0c;输入固定的起手式提示词。 第1步&#xff0c;开启 ControlNet&#xff0c;将需要扩充的图片加载进来&#xff1a; 控制类型选择「Inpaint」&#xff0c;预处理器选择「inpaint_onlylama」&#xff0c;缩放模式选择「缩放后填充空白」&#xff1…

基于SpringBoot+Vue的网约车管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

(Django)初步使用

前言 Django 是一个功能强大、架构良好、安全可靠的 Python Web 框架&#xff0c;适用于各种规模的项目开发。它的高效开发、数据库支持、安全性、良好的架构设计以及活跃的社区和丰富的文档&#xff0c;使得它成为众多开发者的首选框架。 目录 安装 应用场景 良好的架构设计…

Leetcode—763. 划分字母区间【中等】

2024每日刷题&#xff08;175&#xff09; Leetcode—763. 划分字母区间 C实现代码 class Solution { public:vector<int> partitionLabels(string s) {int rightmost[26];int l 0;int r 0;for(int i 0; i < s.length(); i) {rightmost[s[i] - a] i;}vector<…

[C语言]第十一节 函数递归一基础知识到高级技巧的全景探索

目录 11.1. 递归是什么&#xff1f; 11.1.1 递归的思想&#xff1a; 11.2 递归的限制条件 举例1&#xff1a;求n的阶乘 画图推演 举例2&#xff1a;顺序打印⼀个整数的每⼀位 画图推演 11.3. 递归与迭代 举例3&#xff1a;求第n个斐波那契数 11.1. 递归是什么&#xff…

一款基于 Java 的可视化 HTTP API 接口快速开发框架,干掉 CRUD,效率爆炸(带私活源码)

平常我们经常需要编写 API&#xff0c;但其实常常只是一些简单的增删改查&#xff0c;写这些代码非常枯燥无趣。 今天给大家带来的是一款基于 Java 的可视化 HTTP API 接口快速开发框架&#xff0c;通过 UI 界面编写接口&#xff0c;无需定义 Controller、Service、Dao 等 Jav…

【Java数据结构】栈 (Stack)

【本节目标】 1. 栈的概念及使用 2. 相关 OJ 题 一、概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last…

【2024】前端学习笔记11-网页布局-弹性布局flex

学习笔记 网页布局弹性布局&#xff1a;flex案例&#xff1a;flex布局案例 网页布局 在页面布局中&#xff0c;display属性用于设置一个元素的显示方式。它可以指定元素是作为块级元素、内联元素还是充当表格元素显示。 display的常见属性值&#xff1a; block&#xff1a;将…

k8s 中微服务之 MetailLB 搭配 ingress-nginx 实现七层负载

目录 1 MetailLB 搭建 1.1 MetalLB 的作用和原理 1.2 MetalLB功能 1.3 部署 MetalLB 1.3.1 创建deployment控制器和创建一个服务 1.3.2 下载MealLB清单文件 1.3.3 使用 docker 对镜像进行拉取 1.3.4 将镜像上传至私人仓库 1.3.5 将官方仓库地址修改为本地私人地址 1.3.6 运行清…

ensp回顾--聚合链路技术简介与详细案例(构建基于交换机到交换机的聚合链路)

文章目录 什么是聚合链路&#xff1f;聚合链路的工作原理聚合链路的优势使用场景 案例ensp版本图例pc的ip地址具体步骤连通性测试 在现代网络中&#xff0c;聚合链路&#xff08;Link Aggregation&#xff09;是一种常见的技术&#xff0c;用于提高网络连接的带宽和可靠性。本文…

RNN经典案例——构建人名分类器

RNN经典案例——人名分类器 一、数据处理1.1 去掉语言中的重音标记1.2 读取数据1.3 构建人名类别与人名对应关系字典1.4 将人名转换为对应的onehot张量 二、构建RNN模型2.1 构建传统RNN模型2.2 构建LSTM模型2.3 构建GRU模型 三、构建训练函数并进行训练3.1 从输出结果中获得指定…

【可答疑】基于51单片机的智能台灯(含仿真、代码、报告、演示视频等)

✨哈喽大家好&#xff0c;这里是每天一杯冰美式oh&#xff0c;985电子本硕&#xff0c;大厂嵌入式在职0.3年&#xff0c;业余时间做做单片机小项目&#xff0c;有需要也可以提供就业指导&#xff08;免费&#xff09;~ &#x1f431;‍&#x1f409;这是51单片机毕业设计100篇…

数据分析-28-交互式数据分析EDA工具和低代码数据科学工具

文章目录 1 数据分析的七步指南1.1 第一步:问题定义和数据采集1.2 第二步:数据清洗和预处理1.3 第三步:数据探索和分析1.4 第四步:模型建立和分析1.5 第五步:数据可视化1.6 第六步:结果解释和报告1.7 第七步:部署和维护1.8 基础的数据分析库1.9 低代码数据科学工具2 EDA…

STM32 通用定时器

一、概述 STM32内部集成了多个定时/计数器&#xff0c;根据型号不同&#xff0c;STM32系列芯片最多包含8个定时/计数器。其中&#xff0c;TIM6、TIM7为基本定时器&#xff0c;TIM2~TIM5为通用定时器&#xff0c;TIM1、TIM8为高级控制定时器。 1.定时器的类型 基本定时器通用定…

实战案例:结合大模型与爬虫技术实现12306智能查票系统

大语言模型&#xff0c;例如 GPT-4&#xff0c;拥有强大的知识储备和语言理解能力&#xff0c;能够进行流畅的对话、创作精彩的故事&#xff0c;甚至编写代码。然而&#xff0c;它们也面临着一些难以克服的困境&#xff0c;就像一个空有知识却无法行动的巨人 信息滞后&#xf…

Linux 之 安装软件、GCC编译器、Linux 操作系统基础

安装软件、GCC编译器、Linux 操作系统基础 学习任务&#xff1a; 安装 Vmware虚拟机、掌握Ubuntu 系统的使用认识 Ubuntu 操作系统的终端和 Shell掌握软件安装、文件系统、掌握磁盘管理与解压缩掌握 VIM 编辑器、Makefile 基本语法熟悉 Linux 常见指令操作 安装好开发软件&…

[Go语言快速上手]初识Go语言

目录 一、什么是Go语言 二、第一段Go程序 1、Go语言结构 注意 2、Go基础语法 关键字 运算符优先级 三、Go语言数据类型 示例 小结 一、什么是Go语言 Go语言&#xff0c;通常被称为Golang&#xff0c;是一种静态类型、编译型的计算机编程语言。它由Google的Robert Gr…

用HTML5+CSS+JavaScript庆祝国庆

用HTML5CSSJavaScript庆祝国庆 中华人民共和国的国庆日是每年的10月1日。 1949年10月1日&#xff0c;中华人民共和国中央人民政府成立&#xff0c;在首都北京天安门广场举行了开国大典&#xff0c;中央人民政府主席毛泽东庄严宣告中华人民共和国成立&#xff0c;并亲手升起了…

Vue3 中Ref的最佳实践

在vue3中如果我们需要获取一个响应式的变量&#xff0c;可以使用ref来定义一个变量。 const name ref( "" );name.value "test" 定义好后&#xff0c;就可以实现修改状态&#xff0c;更新UI的效果了。 在这个基础上&#xff0c;本文主要讨论跨组件时如何…