掘金团队号上线,助你 Offer 临门! 点击 查看详情
一、题目描述:
给定一个字符串s,请你找出其中不含有重复字符的 最长子串 的长度,s 由英文字母、数字、符号和空格组成
二、思路分析:
分析示例可知,题目要求必须是子串不是序列,也就是说字符之间必须是相邻的,紧挨着的,所以我们可以采取枚举的方式,从字符串第一个下标位置一直遍历到最后,期间使用两个指针卡住一个窗口,这个窗口就是我们要找出的不重复子串,至于是不是最长的,使用一个变量不断做比较这些子串的长度即可。另外因为需要保持子串中的不重复,所以我们需要一个可以去重的数据结构来保存我们遍历过的数据,这个数据结构可以选用HashSet.
1.具体方式是:左指针从左到右依次遍历,当遍历到第二个元素的时候,我们需要把前一个元素从HashSet中删除,这表示重新开始寻找一个新的子串了。
2. 右边的指针需要从零开始递增,不能大于s的长度,当右指针指向元素在HashSet中不存在的时候,这个元素可以加入到HashSet中,然后右指针依次累加,直到碰到一个元素判定其已经在HashSet中存在了,那么从左指针到这个右指针之前的元素算做一个不重复子串,我们计算这个子串和最大长度的大小比较,赋值。然后进行下一轮寻找不重复子串的过程,期间,右指针保持不变,因为从0到现在的位置的子串都是不重复的。
三、AC代码:
class Solution {
public int lengthOfLongestSubstring(String s) {
int len = s.length();
char[] sArr = s.toCharArray();
HashSet set = new HashSet();
int maxLength = 0;
if(s == null || len==0){
return 0;
}
int rk = -1;
for(int i = 0;i<len;i++){
if(i!=0){
//每次移动左指针需要删除set中的上个左指针指向的元素
set.remove(sArr[i-1]);
}
//右指针不断递增直到找到一个和Set中已有元素重复的元素才停止
while(rk+1<len && !set.contains(sArr[rk+1])){
set.add(sArr[rk+1]);
rk++;
}
//计算此时子串长度。
if(rk-i+1>maxLength){
maxLength = rk-i+1;
}
}
return maxLength;
}
}
四、总结 找规律,滑动窗口的概念,需要使用两个指针移动去实现。