题目描述
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 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 由英文字母、数字、符号和空格组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
尝试1
使用双指针遍历记录指针范围内的字符串;
通过判断指针范围内的字符串temp是否包含右指针索引下的字符s.charAt(right)
- 包含:说明加上这个就重复了
所以需要记录最大值,重新截取字符串
左指针的位置:找到重复位置的下一个位置(abcdb)->(3),左指针不能做自增
左指针移动 - 不包含:说明加上这个元素不会重复
直接将这个字符加入temp
右指针++
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s.length() == 0) return 0;
//acdefgamih
int left = 0;//左指针
int right = 1;//右指针
String temp = s.substring(left,right);//记录指针范围内的字符串
int max = 0;//最长字串的长度
while(right < s.length()){
//截取的字串包含下一个字符
if(!temp.contains(s.charAt(right)+"")){
temp = s.substring(left,++right);
}else if(temp.contains(s.charAt(right)+"")){
max = Math.max(max,temp.length());
left += temp.indexOf(s.charAt(right))+1;
temp = s.substring(left,right);
}
}
return max;
}
}
错误原因
当有不重复或者最长字串是包含最后一个字符的,就不会进行max的更新
如:
au
aabcs
尝试2
在尝试1的基础上,将max的更新提出来–循环一次更新一次
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s.length() == 0) return 0;
if (s.length() == 1) return 1;
//acdefgamih
int left = 0;
int right = 1;
String temp = s.substring(left,right);
int max = 0;
while(right < s.length()){
//截取的字串包含下一个字符
if(!temp.contains(s.charAt(right)+"")){
temp = s.substring(left,++right);
}else if(temp.contains(s.charAt(right)+"")){
//max = Math.max(max,temp.length());
left += temp.indexOf(s.charAt(right))+1;
temp = s.substring(left,right);
}
max = Math.max(max,temp.length());//提出来
}
return max;
}
}
优化
之前使用字符串存储指针范围内的字符,
现改用HashMap存储当前字符及其所在位置
如:
abcs:a->0;b->1;c->2;s->3
每次循环:存储当前字符:索引;更新max的值
- 当map中存在当前字符
改变left的值
public int lengthOfLongestSubstring(String s) {
if (s.length() == 0) return 0;
if (s.length() == 1) return 1;
int left = 0;
int right = 1;
Map<Character,Integer> map = new HashMap<>();
map.put(s.charAt(left),0);
int max = 0;
while(right < s.length()){
if(map.containsKey(s.charAt(right)))
left = Math.max(left,map.get(s.charAt(right))+1);//当abba时,遍历到第二个a会去找第一个a的位置,所以取最大值
map.put(s.charAt(right),right++);
max = Math.max(max,right-left);
}
return max;
}