给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
解析:
初始思路:一开始我想用双指针的思想,几层for循环判断,但一直没有成功。
这里记录一下未成功代码,读者可直接略过。
错误代码:
class Solution {
public int lengthOfLongestSubstring(String s) {
int i=0,j=1;
int max=0;
if(j==s.length()) max=1;
while(j<s.length()){
int flag=0;
for(int k=i;k<j;k++){
if(s.charAt(k)==s.charAt(j)){
i++;
flag=1;
break;
}
}
if((j-i)>max) max=j-i;
if(flag==0){
j++;
}
}
return max;
}
}
正确解析:用哈希表结构实现,将子串加入到容器中,每次加入前判断哈希表中是否有相同的元素。如果有,则计算此时子串的长度,将此时子串的第一个字符移走,继续检查是否有重复元素。注意,这里是没有回溯的,因为容器中已存入的元素是不可能重复的,所以继续上次循环检查到的元素 继续检查即可。
Java:HashSet
class Solution {
public int lengthOfLongestSubstring(String s) {
HashSet <Character> maxstr=new HashSet<Character>();
int n=s.length();
int j=0,max=0;
for(int i=0;i<n&&j<n;i++){
if(i!=0){
maxstr.remove(s.charAt(i-1)); //这里注意是删除i-1位置处的
}
while(j<n&&!maxstr.contains(s.charAt(j))){
maxstr.add(s.charAt(j));
j++;
}
max=Math.max(max,j-i);
}
return max;
}
}
C++:unordered_set
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_set<char> maxstr;
int n=s.size();
int j=0,max2=0;//注意这里不能声明为max,因为会与max()方法冲突
for(int i=0;i<n&&j<n;i++){
if(i!=0){
maxstr.erase(s[i-1]);
}
while(j<n&&!maxstr.count(s[j])){
maxstr.insert(s[j]);
j++;
}
max2=max(max2,j-i);
}
return max2;
}
};