算法——滑动窗口之找到字符串中所有的字母异位词,串联所有单词的子串

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

题目:. - 力扣(LeetCode)

6.1如何快速判断两个字符串是否是异位词

假设现在有s1 = 'aabca',s2 = 'abaca',那么这两个就是异位词,容易想到的判断方法就是将两个字符串按照字典序排序,再依次比较,但是时间复杂度很高;我们看看下面这种解法:不难发现如果两个字符串为异位词,那么他们之间的相同字符的个数也是相同的,如a有3个,b一个,c一个.那么我们就可以通过判断两个字符串中每种字符的个数是否相同,相同则是异位词,这个功能我们可以利用hash表来实现

6.2解决问题
 s = "cbaebabacd", p = "abc"

暴力解法当然是找出s中的所有长度为p.length 的子串,通过hash来判断是否为异位词,

我们在暴力解法上进行优化:

当我们判断前三个字符后,没必要将right回到b的位置再继续列举,因为实际上我们下一个要判断的是字符串"bae",但是我们在hash2中已经记录了b a的信息,我们只需将c移除hash2,再将a移入hash2即可.这就是滑动窗口的问题,与前面的题目不同的是,这里我们维护的窗口长度是固定的

滑动窗口步骤:

in表示right的元素,out表示left的元素

(1)进窗口 :hash2[in]++

(2)判断 如果 right - left + 1 > p.length,那么就要出窗口

(3)出窗口:hash2[out]--

(4)更新结果:判断hash1 和 hash2 字符情况是否相同

在此步骤判断的时候,如果按照上述的步骤来,我们可以建立两个长度为26的数组作为hash表,每次变量两个数组来判断是否相同,加上滑动窗口,时间复杂度为O(26n),即O(n)

这里是因为判断的为单个字符的数量,但是如果题目是要判断字符串的数量呢??

因此我们进行优化:利用count 来统计窗口中"有效字符"的个数

假设我们的字符串为:

我们的步骤是:

在进窗口时:

如此时,在hash2[in] ++之后,我们需要判断hash2[in] 与hash1[in] 的大小关系,如果hash2[in] <= hash1[in],那么说明我们加进来的是一个"有效字符",所谓的有效字符即我们这个字符能低效掉hash1中的某个字符

我们将right++,

此时由于hash2[in] > hash1[in],说明不是一个有效字符,那么count++,同理right再++

为有效字符,count更新为2

我们只需判断count 是否 等于 p.length即可,如果相等,那么即为异位词,并且我们这个判断可以穿插在每一次外循环中,因为只有count = p.length才能更新结果

当我们再次right++后,

这时候就要出窗口了,再出窗口时,我们依旧要判断hash2[out] 与hash1[out] 的大小关系,如果hash2[out] <= hash1[out],那么说明我们移出去的是一个"有效字符",那么count--,反之则不用

题解:

 public static List<Integer> findAnagrams(String s, String p) {List<Integer> ret = new ArrayList<>();int[] hash1 = new int[26];int[] hash2 = new int[26];for(int i = 0; i < p.length(); i++){hash1[p.charAt(i) - 'a']++;}for(int left = 0,right = 0,count = 0; right < s.length(); right++){int in = s.charAt(right) - 'a';hash2[in]++;if(hash2[in] <= hash1[in]){count++;}if(right - left + 1 > p.length()){int out = s.charAt(left++) - 'a' ;if(hash2[out] <= hash1[out]) {count--;}hash2[out]--;}if(count == p.length()){ret.add(left);}}return ret;}

7.串联所有单词的子串

题目:. - 力扣(LeetCode)

理解题目后,如果我们做过滑动窗口的第6题,就会发现这道题和异位词实际上非常相似,只不过将原先的一个个单词转化为一个个字符串

具体的算法原理在第6题已经说过,我们来看看不同点

(1)哈希表

本题的hash表需要用Map<String,int>来实现

(2)left和right的次数

题目规定,words里面的单词都是等长的,我们记这个长为len,那么我们的left和right每次就都要移动len个字符,以实现跨过一个单词

(3)滑动窗口的执行次数

题目可能会出现"lingmindraboofooowingdingbarrwingmonkeypoundcake" ["fooo","barr","wing","ding","wing"]这样的情况,即left和right可能不是从0下标开始移动的

如上图,我们会发现找不到答案,而事实上还有下面几种可能:

当我们left从m开始的时候,会发现和第一种是一样的,因此我们只需要进行4次,而刚好是执行次数刚好是字符串的长度

也是由于这个问题,我们right的循环结束条件应该为:right + len <= s.length

题解:

 class Solution {public List<Integer> findSubstring(String s, String[] words) {List<Integer> list = new ArrayList<>();Map<String,Integer> hash1 = new HashMap<>();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<>();for(int left = i,right = i,count = 0; right + len <= s.length(); right += len){String 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){String 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){list.add(left);}} }return list;}}

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

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

相关文章

javascript实现解决浮点数加减乘除运算误差丢失精度问题【收藏点赞】

相信程序都会遇到这样的问题&#xff0c;有时需要在js上做运算合计等浮点数加减乘除&#xff0c;但会有些浮点数会有误差问题。下面用js来解决浮点数加减乘除运算误差丢失精度这个请 【收藏点赞】。 是程序都会在浮点数加减乘除上有误差问题&#xff0c;这是计算机二进制生成的…

Node.Js编码注意事项

Node.js 中不能使用 BOM 和 DOM 的 API&#xff0c;可以使用 console 和定时器 APINode.js 中的顶级对象为 global&#xff0c;也可以用 globalThis 访问顶级对象 浏览器端js的组成 Node.js中的JavaScript组成 相比较之下发现只有console与定时器是两个API所共有的&#xff…

23.复习

1.设置输出数字宽度 #include <iostream>using namespace std;int main(){int a123456789,b0,c-1;printf("%8d %8d %8d",a,b,c);return 0; }2.保留小数点位数 #include <iostream>using namespace std;int main(){double a;cin>>a;printf("…

3款免费又实用的良心软件,功能强大到离谱,白嫖党的最爱

闲话不多说&#xff0c;直接上硬货&#xff01; 1、酷狗概念版 这款正版音乐APP可谓是“良心之作”。不论你是新用户还是老用户&#xff0c;只要踏入概念版的门槛&#xff0c;即可获得3个月VIP作为见面礼。更令人惊喜的是&#xff0c;每天只需轻松一点播放歌曲&#xff0c;即…

IDEA管理Git + Gitee 常用操作

文章目录 IDEA管理Git Gitee 常用操作1.Gitee创建代码仓库1.创建仓库1.点击新建仓库2.完成仓库信息填写3.创建成功4.管理菜单可以修改这个项目的设置 2.设置SSH公钥免密登录基本介绍1.找到.ssh目录2.执行指令 ssh-keygen3.将公钥信息添加到码云账户1.点击设置2.ssh公钥3.复制.…

海思Hi3403V100方案双目视频融合模组测试

Hi3403V100是海思面向高端市场应用推出的专业 Ultra-HD Smart IP Camera SOC&#xff0c;该芯片最高支持四路sensor输入&#xff0c;支持最高4K60的ISP图像处理能力。 海思Hi3403V100方案双目视频模组采用了海思Hi3403V100方案核心板双目视频融合IMX334 Sensor板测试&#xff…

一文带你搞定python脚本(.py)打包为可执行文件(.exe)

文章目录 01、为什么要打包Python脚本&#xff1f;02、打包步骤&#xff1f;第一步&#xff1a;环境配置与操作包安装第二步&#xff1a;开始打包第三步&#xff1a;输入打包命令ICO图片生成示例&#xff1a;总结&#xff1a; 03、多个.py文件打包import 和 from ... import *用…

鸿蒙开发学习入门教程之环境配置

最近鸿蒙开发越来越火&#xff0c;各个大厂都有鸿蒙版本的计划和宣传&#xff0c;看这个趋势&#xff0c;可能会在几年内发展壮大&#xff0c;为我们移动端码农开辟一片新的职场。所以现在开始学起来还是很有必要的。今天就一起开始配置环境搞起来吧。 首先&#xff0c;找到官…

当金蝶遇上BI,马上就能看到数据可视化效果

最近整理咨询内容时发现&#xff0c;很多企业用户在咨询时都会问是否有行业案例&#xff0c;究其原因时他们没用过BI数据分析&#xff0c;不知道BI可以做什么&#xff0c;能做到什么地步。其实&#xff0c;要知道这些东西还不简单&#xff0c;只需要注册奥威BI软件&#xff0c;…

Window10数据库崩溃启动失败,MySQL8.0.30通过data文件夹恢复数据库到Docker

背景&#xff1a; 昨天关机前还在使用mysql&#xff0c;一切正常&#xff0c;但今天打开电脑&#xff0c;发现mysql启动不起来了&#xff0c;老是提示端口占用&#xff0c;但是系统也没有新安装什么软件&#xff0c;而且通过查询nat命令也没发现3306端口占用。而且修改成3307等…

基于SpringBoot的农产品特色供销系统(蔬菜商城)

基于SpringBoot的农产品特色供销系统&#xff08;蔬菜商城&#xff09; 系统介绍 该系统使用Java、MySQL、Redis、Spring Boot和HTML等技术作为系统的技术支撑&#xff0c;实现了以下功能模块&#xff1a; &#xff08;1&#xff09;后台管理模块&#xff0c;包括权限、日志、…

11---数字温度 OR 湿度传感器电路设计

视频链接 数字温度or湿度传感器电路设计02_哔哩哔哩_bilibili 数字温度 OR 湿度传感器电路设计 1、温湿度传感器 DHT11 DHT11是一款有已校准数字信号输出的温湿度传感器。 其精度湿度-5%RH&#xff0c; 温度-2℃&#xff0c;量程湿度20-90%RH&#xff0c; 温度0~50℃。 D…