LeetCode3 无重复字符的子串
题目:
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
示例 4:
输入: s = ""
输出: 0
提示:
0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成
Related Topics 哈希表 双指针 字符串 Sliding Window
方法
暴力法
- 时间复杂度:O(n2)
- 空间复杂度:O(n)
class Solution {
public int lengthOfLongestSubstring(String s) {
int strLength = s.length();
int max = 0;
for(int i =0;i<strLength;i++)
for(int j=i+1;j<=strLength;j++)
if(!isRept(s,i,j)) max = Math.max(max,j-i);
return max;
}
// 判断子字符串中是否有重复字符
public boolean isRept(String s,int begin,int end){
Set<Character> charSet = new HashSet<>();
for(int i=begin;i<end;i++){
Character x = s.charAt(i);
if(charSet.contains(x))return true;
charSet.add(x);
}
return false;
}
}
滑动窗口
用set保存已存在的字符,
如果end处的字符重复,就将start减1,每次去除一个滑动窗口头部的重复字符直到删除的重复值不存在
如果end处的字符不重复,证明字符串没有重复的,则对比最大值
- 时间复杂度:O(n),n为字符串长度,可能为2n
- 空间复杂度:O(n),
class Solution {
public int lengthOfLongestSubstring(String s) {
int start = 0;
int end = 0;
int res = 0;
Set<Character> set = new HashSet<>();
while(end<s.length()){
if(set.contains(s.charAt(end))){
set.remove(s.charAt(start));
start++;
}else{
set.add(s.charAt(end));
end++;
res = Math.max(res,end-start);
}
}
return res;
}
}
滑动窗口优化版
用map记录已经遍历的字符,并记录当前字符在遍历过子串中最后的位置,从而一次定位到当end指针指向重复字符时的起始位置
- 时间复杂度:O(n),n为字符串长度
- 空间复杂度:O(n)
class Solution {
public int lengthOfLongestSubstring(String s) {
Map<Character,Integer> map = new HashMap<>();
int res = 0;
for(int start=0,end=0;end<s.length();end++){
if(map.containsKey(s.charAt(end))){
start = Math.max(start,map.get(s.charAt(end)));
}
res = Math.max(res,end-start+1);
map.put(s.charAt(end),end+1);
}
return res;
}
}
滑动窗口优化版2
由于字符串的长度有限,我们可以用数组代替Map
- 时间复杂度:O(n),n为字符串长度
- 空间复杂度:O(128)
public class Solution {
public int lengthOfLongestSubstring(String s) {
int res = 0;
int[] index = new int[128];
for(int start=0,end=0;end<s.length();end++){
start = Math.max(start,index[s.charAt(end)]);
res = Math.max(res,end-start+1);
index[s.charAt(end)] = end+1;
}
return res;
}
}
Js版本:
- 时间复杂度:O()
- 空间复杂度:O()
var lengthOfLongestSubstring = function(s) {
let start = 0,max = 0;
const map = new Array(128);
for(let r=0;r<s.length;r++){
if(map[s[r]]!==undefined){
start = Math.max(start,map[s[r]]);
}
max = Math.max(max,r-start+1);
map[s[r]]=r+1;
}
return max;
};
滑动窗口优化版3
用数组保存无重复字符串
Js版本
- 时间复杂度:O()
- 空间复杂度:O()
var lengthOfLongestSubstring = function(s) {
let max = 0;
let arr =[];
for(let i=0;i<s.length;i++){
let index = arr.indexOf(s[i]);
if(index!=-1){
arr.splice(0,index+1);
}
arr.push(s[i]);
max = Math.max(max,arr.length);
}
return max;
};
分类:
LeetCode Hot100
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理