[Java][算法 滑动窗口]Day 02---LeetCode 热题 100---08~09

第一题  无重复字符串的最长子串

思路

其实就是在字符串S中 找到没有重复的最长子串的长度  这道题的难点就是在于如何判断最长并且无重复

首先 最长长度  可以使用变量max记录保存   

再者 判断有无重复  最简单的方法就是  暴力遍历法  即对于每次找的子串都再次寻找遍历一次  判断是否已有字符  自然  这种方法判断的话 时间复杂度会不是一般的高

当然 算法优化我们慢慢再讨论  最直接的思路就是如此

解法一:暴力法

我们的暴力当然和上述思路不太一样  我们对于是否重复  可以直接利用Map集合key不能重复的特点  然后使用containKey()方法直接进行判断

class Solution {public static int lengthOfLongestSubstring(String s) {
// 对于S的特殊情况直接返回0if(s==null || s.length()==0) return 0;
//将S转化为char数组[]  遍历该数组 然后进行判断char[] charArray = s.toCharArray();int max=1;Map<Character,Integer> map=new HashMap<>();
//遍历  每次遍历开始就是认定为子串的起始字符for(int i=0;i< charArray.length;i++){
//每次记录完一次后 需要把map清空map.clear();map.put(charArray[i],i); //将第一个字符放入for(int j=i+1;j< charArray.length;j++){if(map.containsKey(charArray[j])){ // 利用containKey方法直接判断if(map.size()>max) max=map.size(); // 判断当前map长度和max进行比较break;}else{map.put(charArray[j],j);}}if(map.size()>max) max=map.size();}return max;}
}

解法二:滑动窗口法

所谓滑动窗口,其实就是在字符串中先选定一段,把这段作为一个可以滑动的窗口,这个窗口类似于队列,每次判断队列中字符是否满足题目条件,不满足即向左滑动(这是整体情况下 一般是向左  自然 也可以只会滑动右边界),滑动窗口的时候,自然左边会少一位,右边会多一位。

class Solution {public int lengthOfLongestSubstring(String s) {if (s.length()==0) return 0;HashMap<Character, Integer> map = new HashMap<Character, Integer>();int max = 0;int left = 0;for(int i = 0; i < s.length(); i ++){if(map.containsKey(s.charAt(i))){ //判断是否存在已有队列中
//有的话 找到map中该重复的元素的索引位置 判断两者索引大小 通过对索引的判断 不断向右滑动变化起点left = Math.max(left,map.get(s.charAt(i)) + 1);  }map.put(s.charAt(i),i);//不存在则添加到map中max = Math.max(max,i-left+1); // 更新最大长度}return max;}
}

第二题  找到字符串中所有字母异位词

思路

和第一题类似 也是遍历找子串  只是这个题目判断依据  不是重复 而是找异位词  异位词的定义我们之前也遇到过 简单来说 就是字母组成一样   如果是异位词 那么排序后的字符串两者一定是一样的  所以我们对其的判断方式就是排序后是否一样  那么这道题的解题思路就很明确

需要注意字符串长度  判null等特殊情况

解法一:暴力法

同样的 直接暴力遍历  然后判断是否为异位词就行即可

class Solution {public List<Integer> findAnagrams(String s, String p) {if(s==null||p.length()>s.length()) return new ArrayList<>();char[] pArray = p.toCharArray();Arrays.sort(pArray);ArrayList<Integer> list = new ArrayList<>();int i=0;int l=p.length();//   abvdef   abfor(i=0;i<=s.length()-l;i++){char[] sArray = s.substring(i, i + l).toCharArray();Arrays.sort(sArray);if(String.valueOf(pArray).equals(String.valueOf(sArray))){list.add(i);}}return list;}
}

我们是采用排序的方式进行判断异位词  当然也可以采用哈希表映射 统计字母次数的方式  代码如下

class Solution {public List<Integer> findAnagrams(String s, String p) {int sLen = s.length(), pLen = p.length();if (sLen < pLen) {return new ArrayList<Integer>();}List<Integer> ans = new ArrayList<Integer>();int[] sCount = new int[26];int[] pCount = new int[26];for (int i = 0; i < pLen; ++i) {++sCount[s.charAt(i) - 'a'];++pCount[p.charAt(i) - 'a'];}if (Arrays.equals(sCount, pCount)) {ans.add(0);}for (int i = 0; i < sLen - pLen; ++i) {--sCount[s.charAt(i) - 'a'];++sCount[s.charAt(i + pLen) - 'a'];if (Arrays.equals(sCount, pCount)) {ans.add(i + 1);}}return ans;}
}

解法二:滑动窗口法

我们不再分别统计滑动窗口和字符串 p 中每种字母的数量,而是统计滑动窗口和字符串 p 中每种字母数量的差;并引入变量 differ来记录当前窗口与字符串 p 中数量不同的字母的个数,并在滑动窗口的过程中维护它。

在判断滑动窗口中每种字母的数量与字符串 ppp 中每种字母的数量是否相同时,只需要判断 differ是否为零即可

class Solution {public List<Integer> findAnagrams(String s, String p) {List<Integer> res = new ArrayList<Integer>();int sLen = s.length();int pLen = p.length();if(sLen < pLen) {return res;}//表示字母出现次数差距//count[x] = 0  表示 s与p中字母x出现次数相同 都出现了n次(n>=0)//count[x] = n  表示 在s中字母x出现次数比p多 多出现了n次(n>0)//count[x] = -n 表示 在s中字母x出现次数比p少 少出现了n次(n>0)int[] count = new int[26];for(int i = 0; i < pLen; i++){++count[s.charAt(i)-'a'];--count[p.charAt(i)-'a'];}//表示字母差异个数int differ = 0;for(int j = 0; j < 26; j++){if(count[j]!=0)++differ;}if(differ==0){res.add(0);}//向右滑动for(int i = 0; i < sLen - pLen; i++){//缩减时只考虑count[x]==1与count[x]==0的情况//因为缩减时字母x减少,count[x]会减去1//(1)count[x]==1时(次数差距1次,不相同)  //count[x]==0 -> 次数相同 -> 不相同变相同,字母差异个数减少1 -> differ--//(2)count[x]==0时(次数相同)  //count[x]==-1 -> 次数差距变为1次->相同变不相同 ,字母差异个数增加1 -> differ++//(3)count[x]==-1时(次数不相同) -> count[x]==-2 次数还是不相同-> 字母差异数不变//(4)count[x]==2时(次数不相同)  -> count[x]==1 次数还是不相同-> 字母差异数不变//左缩减一位,iif (count[s.charAt(i) - 'a'] == 1) {  //窗口中s子串左边减少一个s[i]的数量(把原来多出来的1个s[i]去掉,变得相同)//两个字符串字母差距缩小--differ;} else if (count[s.charAt(i) - 'a'] == 0) {  //窗口中s子串左边减少一个s[i]的数量(把原来相同数量的s[i]的减少了1个,数量变得不相同)//两个字符串字母差距增大++differ;}//窗口中s子串左边减少一个字母s[i]--count[s.charAt(i) - 'a'];//添加时只考虑count[x]==-1与count[x]==0的情况,原因分析与缩减时类似//右添加一位,i+pLenif (count[s.charAt(i + pLen) - 'a'] == -1) {  //窗口中s子串右边增加一个s[i+pLen]的数量(把原来缺少的1个s[i]加上,数量变得相同)//两个字符串字母差距缩小--differ;} else if (count[s.charAt(i + pLen) - 'a'] == 0) {  //窗口中s子串右边增加一个s[i+pLen]的数量(把原来相同数量的s[i]多加了1个,变得不相同)//两个字符串字母差距增大++differ;}//窗口中s子串右边增加一个字母s[i+pLen]++count[s.charAt(i + pLen) - 'a'];//两个字符串字母差距为0if (differ == 0) {res.add(i + 1);}}return res;  }
}

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

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

相关文章

【JAVA WEB】JavaScript--函数 作用域 对象

目录 函数 语法格式 示例 定义没有参数列表&#xff0c;也没有返回值的一个函数 定义一个有参数列表 &#xff0c;有返回值的函数 关于参数个数 函数表达式 作用域 作用域链 对象 基本概念 创建对象 1.使用 字面量 创建对象 2.使用new Object()创建对象 3.使…

SNMP 简单网络管理协议、网络管理

目录 1 网络管理 1.1 网络管理的五大功能 1.2 网络管理的一般模型 1.3 网络管理模型中的主要构件 1.4 被管对象 (Managed Object) 1.5 代理 (agent) 1.6 网络管理协议 1.6.1 简单网络管理协议 SNMP 1.6.2 SNMP 的指导思想 1.6.3 SNMP 的管理站和委托代理 1.6.4 SNMP…

【Zigbee课程设计系列文章】Zigbee开发环境搭建

【Zigbee课程设计系列文章】Zigbee开发环境搭建 前言IAR 下载安装Z-Stack协议栈安装 &#x1f38a;项目专栏&#xff1a;【Zigbee课程设计系列文章】&#xff08;附详细使用教程完整代码原理图完整课设报告&#xff09; 前言 &#x1f451;由于无线传感器网络&#xff08;也即…

C语言——枚举类型

&#x1f4dd;前言&#xff1a; 在之前的文章中我们已经讲解了自定义类型中的结构体类型和联合体类型&#xff0c;现在我们再充分学习一下C语言中的枚举类型&#xff1a; 1&#xff0c;什么是枚举类型 2&#xff0c;枚举类型的定义和变量的声明 3&#xff0c;对变量进行赋值 &a…

[计算机网络]---网络编程套接字

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、基础知识…

Android Graphics 图像显示系统 - 开篇

“ 随着学习的不断深入和工作经验的积累&#xff0c;欲将之前在博客中整理的Android Graphics知识做进一步整理&#xff0c;并纠正一些理解上的错误&#xff0c;故开设Graphics主题系列文章 ” 序言 由于工作需要&#xff0c;也源于个人兴趣&#xff0c;终于下决心花时间整理一…

【前端设计】炫酷导航栏

欢迎来到前端设计专栏&#xff0c;本专栏收藏了一些好看且实用的前端作品&#xff0c;使用简单的html、css语法打造创意有趣的作品&#xff0c;为网站加入更多高级创意的元素。 html <!DOCTYPE html> <html lang"en"> <head><meta charset&quo…

车载诊断协议DoIP系列 —— DoIP APP车辆识别和声明请求报文

车载诊断协议DoIP系列 —— DoIP APP车辆识别和声明请求报文 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江…

Boost.Asio-使用Boost.Asio和OpenWeatherMap API获取天气的简单示例

OpenWeatherMap API是一个提供天气数据的开放接口&#xff0c;可以通过该接口获取全球范围内的实时天气。 1.获取OpenWeatherMap API的密钥 去官网https://openweathermap.org注册后&#xff0c;自主生成密钥&#xff0c;如图 2.获取用的代码(方法1) #include "stdafx.h&…

BFS与DFS初级练习(排列数字,n-皇后,走迷宫)

BFS与DFS初步了解 DFS&#xff08;深度优先搜索&#xff09;和BFS&#xff08;广度优先搜索&#xff09;是两种常用的图遍历算法。 DFS是一种递归的搜索算法&#xff0c;它从起始节点开始&#xff0c;沿着路径依次访问与当前节点相邻的未访问节点&#xff0c;直到无法继续访问…

[NSSRound#17 Basic]WEB

1.真签到 看robots.txt 密码先base32再base64得到md5加密的密文&#xff0c;在线解得到密码为Nss hint用16进制转字符串&#xff0c;提示新生赛遇到过 是一个敲击码加密 账号是ctfer,登录之后源码提示在F111n4l.php 要求nss参数若比较等于732339662&#xff0c;但是不能是数…

助眠神器小程序源码|白噪音|小睡眠|微信小程序前后端开源

安装要求和说明后端程序运行环境&#xff1a;NginxPHP7.4MySQL5.6 PHP程序扩展安装&#xff1a;sg11 网站运行目录设置为&#xff1a;public 伪静态规则选择&#xff1a;thinkphp 数据库修改文件路径&#xff1a;/config/database.php需要配置后端的小程序配置文件&#xff0c;…