当前位置: 首页 > news >正文

LeeCode 3. 无重复字符的最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。

示例 2:

输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。

示例 3:

输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。

提示:

0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成

思路:

这道题主要用到思路是:滑动窗口

什么是滑动窗口?

其实就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列!

如何移动?

我们只要把队列的左边的元素移出就行了,直到满足题目要求!

一直维持这样的队列,找出队列出现最长的长度时候,求出解!

时间复杂度:O(n)

1.map存储

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 ++){/**1、首先,判断当前字符是否包含在map中,如果不包含,将该字符添加到map(字符,字符在数组下标),此时没有出现重复的字符,左指针不需要变化。此时不重复子串的长度为:i-left+1,与原来的maxLen比较,取最大值;2、如果当前字符 ch 包含在 map中,此时有2类情况:1)当前字符包含在当前有效的子段中,如:abca,当我们遍历到第二个a,当前有效最长子段是 abc,我们又遍历到a,那么此时更新 left 为 map.get(a)+1=1,当前有效子段更新为 bca;2)当前字符不包含在当前最长有效子段中,如:abba,我们先添加a,b进map,此时left=0,我们再添加b,发现map中包含b,而且b包含在最长有效子段中,就是1)的情况,我们更新 left=map.get(b)+1=2,此时子段更新为 b,而且map中仍然包含a,map.get(a)=0;随后,我们遍历到a,发现a包含在map中,且map.get(a)=0,如果我们像1)一样处理,就会发现 left=map.get(a)+1=1,实际上,left此时应该不变,left始终为2,子段变成 ba才对。为了处理以上2类情况,我们每次更新left,left=Math.max(left , map.get(ch)+1).另外,更新left后,不管原来的 s.charAt(i) 是否在最长子段中,我们都要将 s.charAt(i) 的位置更新为当前的i,因此此时新的 s.charAt(i) 已经进入到 当前最长的子段中!*/if(map.containsKey(s.charAt(i))){left = Math.max(left,map.get(s.charAt(i)) + 1);}map.put(s.charAt(i),i);// 当前无重复字符的最长子串长度=i-left+1max = Math.max(max,i-left+1);}return max;}
}

执行用时分布
5ms
击败68.29%使用 Java 的用户
消耗内存分布
43.44MB
击败23.30%使用 Java 的用户

2.把map用数组代替

int[] bitmap = new int[128];
char 整数对应数组存储字符串下标
相当于这个数组里存储的是字符对应的自己的最左下标

class Solution {public int lengthOfLongestSubstring(String s) {if (s.length()==0) return 0;char[] sCharArray = s.toCharArray();int[] bitmap = new int[128];int max = 0;//最左边下标int left = 0;for(int i = 0; i < s.length(); i ++){char cur = sCharArray[i];if(bitmap[cur] > 0){left = Math.max(left,bitmap[cur]);}bitmap[cur] = i + 1;// 当前无重复字符的最长子串长度=i-left+1max = Math.max(max,i-left+1);}return max;}
}

执行用时分布
1ms
击败100.00%使用 Java 的用户
消耗内存分布
42.25MB
击败88.21%使用 Java 的用户

相关文章:

  • Kafka(二)【文件存储机制 生产者】
  • 2024 年入局大模型:是否为时已晚?
  • 3.Eureka注册中心
  • 【C/C++】C/C++编程——C++ 开发环境搭建
  • Vue3+TS+dhtmlx-gantt实现甘特图
  • typing python 类型标注学习笔记
  • Vue3 Hooks函数使用及封装
  • Qt容器QMap(映射)
  • leetcode---Z字形变换
  • 数据结构<1>——树状数组
  • 汇编中的标签与C语言的函数对比与区别
  • Windows10上通过MSYS2编译FFmpeg 6.1.1源码操作步骤
  • 时间序列大模型:TimeGPT
  • 大数据平台红蓝对抗 - 磨利刃,淬精兵!
  • 搭建k8s集群实战(一)系统设置
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • 【EOS】Cleos基础
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • Fastjson的基本使用方法大全
  • gf框架之分页模块(五) - 自定义分页
  • js中的正则表达式入门
  • Mithril.js 入门介绍
  • Octave 入门
  • QQ浏览器x5内核的兼容性问题
  • Sublime Text 2/3 绑定Eclipse快捷键
  • WePY 在小程序性能调优上做出的探究
  • 百度地图API标注+时间轴组件
  • 前端
  • 前端面试之闭包
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 入口文件开始,分析Vue源码实现
  • 小程序开发中的那些坑
  • 赢得Docker挑战最佳实践
  • 优化 Vue 项目编译文件大小
  • ​人工智能书单(数学基础篇)
  • (阿里云万网)-域名注册购买实名流程
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (转)EXC_BREAKPOINT僵尸错误
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .cn根服务器被攻击之后
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .NET Core 2.1路线图
  • .NET 命令行参数包含应用程序路径吗?
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .net最好用的JSON类Newtonsoft.Json获取多级数据SelectToken
  • /3GB和/USERVA开关
  • @RequestParam,@RequestBody和@PathVariable 区别
  • [AHOI2009]中国象棋 DP,递推,组合数
  • [APIO2015]巴厘岛的雕塑
  • [Arduino学习] ESP8266读取DHT11数字温湿度传感器数据
  • [Assignment] C++1
  • [C#C++]类CLASS