Description——–
Description——
Given a string, find the length of the longest substring without repeating characters.
Examples:
Given “abcabcbb”, the answer is “abc”, which the length is 3.
Given “bbbbb”, the answer is “b”, with the length of 1.
C++解法:
关于 find()函数 :
找到相应字符串后会返回其index位置 . 找不到就返回 -1
利用两个指针 : 子串的头指针 i ,和尾指针 j .
人类思维 : 找到一个子串之后 ,顺次判断之后的字符是否在这个子串之内 ,
如果不在, 顺次判断下一个字符 ,
如果在 :
— 记录下这个子串的长度 和 坐标
— 指针跳转:
——- i 后移,
——- j 跳转到 find()函数返回的位置 .
对于 “abcdefc” 来说 , 当我们发现 c 这个字符 在 abcdef 子串里面的时候 ,
bcdef ,cdef ,def 就通通失去了成为最长子串的机会, 那么 i 也就不应指向b/c , 而是应该从 d 开始寻找 .
此时 i 应等于 i + find(‘c’) + 1 ; j = i + 1 .
存储合适的子串:
当 len > maxlen时候才进行存储. m n 存储当前最长的子串的坐标 ,
class Solution {
public:
int inString(char ch,string sub){ //在子串中寻找
int pos = sub.find(ch);
return pos;
}
string lengthOfLongestSubstring(string s) {
int m = 0,n = 0,maxlen = 1 ;
int i= 0 ,j = 1; //初始化两个指针
for( ; j < s.length() ; ){
int pos = inString(s[j],s.substr(i,j-i)); //关于substr(i,j-i) 1.
if( pos == -1 ){ //不在子串之内.
if(s.substr(i,j-i).length() >= maxlen){
m = i, n = j;
maxlen = s.substr(i,j-i).length();
} j++;continue;
}else{ // 表示在子串内 .
i = i+pos+1; j = i+1;
}
}
return s.substr(m,n-m+1);
}
};
int main () {
Solution a;
string temp = a.lengthOfLongestSubstring("abcabcbb") ;
cout<<"Result:"<<temp<<endl;
return 0;
//1. 因为substr(start,len) 的参数start是起始index, len是要取的长度,所以我们用 j - i 表示要取的长度.
python解法:
class Solution:
def lengthOfLongestSubstring(self, s):
dic, res, start, = {}, 0, 0
for i, ch in enumerate(s): # 遍历 s 串
if ch in dic: # 说明 ch 以前出现过
res = max(res, i-start)
] start = max(start, dic[ch]+1)
dic[ch] = i
return max(res, len(s)-start)
# 测试代码
a = Solution()
a.lengthOfLongestSubstring("abba")
以 “abba” 为例 ,我们在 dic[ch] = i 后面加一个 print(dic,res,start) 语句:
start = dic[ch]+1 ,所以说 start 记录了重复字符最新出现的位置.比如”abab” ,当 i = 2 ,a重复了 ,start等于1 ,当i = 3,b又重复了,start等于2 , 当有重复的字符出现的时候 ,start 会后移.
res = max( res , i-start ) ,如”aabcdb” ,当 i==1 a重复,start = 1,当i==5时,b重复 ,res=5-start==4 .那么我们可以看出: res 记录的是”从一次遇到重复字符 到 这一次出现重复字符 ,i 所扫过的长度”. 我们用 res = max(res, i-start) 来保持 res 的更新 .但是这样并不保险 .因为如果后面再也没有重复字符了 比如 :aaghjk,那么 res 不就没法更新了吗?
那么我们就需要一个 len(s)-start , len(s)-start表明 :最长子串当然也有可能是 dic[ch]+1 后面的串, .但是这个说法并不准确, 比如 “addd” ,当你扫描到重复的 d 的时候,我们并不能说最长子串在 d 之后 .所以需要 res 来修正他.