1. 题意
leetcode 03: 无重复字符的最长子串.
tips:简单说下子串(substring) 和 子序列(subsequence)
就是子串在原串中一定连续
所有的子序列包含所有的子串
exampls: “abcde” 中 “abc” ,"bcde"是子串,“ade”,"ce"是子序列
2. 题解
双指针、滑动窗口、哈希表
考虑当前的序列加入下一个字符的情况
(1)当前字符未在该序列中出现
右指针右移
(2)当前字符在该序列中出现
左指针不断向右移动,取消标记当前左指针所指向字符,直到找到该字符出现的第一个位置停止。 再将左指针右移动一位,此时左右指针所确定的一个序列为一个合法序列。
(3)更新合法序列长度,标记当前字符已经出现。
扩展:
(1) 为什么只需要找到第一个重复字符?
因为只可能有一个重复字符,初始化的时候空字符串是个合法字符串,接着执行的每一步都保障了当前左右指针所确定的字符串合法。
(2) 如果要求的是串本身而非长度?(任意一个,所有)
建立个二元组(std::pair
)只需要合法时将串合法时的左右指针存入并更新即可
int lengthOfLongestSubstring(char * s){
int vis[300] = {0};//记录字符是否出现
int l = 0;//左指针
int ret = 0;//保存长度
for(int i = 0;i < strlen(s);i++){
if(vis[s[i]]){
//已经出现该字符
//右移左指针,直到找到重复的该字符
while(s[l] != s[i]){
vis[s[l]] = 0;//取消标记
l++;
}
l++;//下一字符才合法
}
ret = ret > (i - l + 1) ? ret : i - l + 1;//更新长度
vis[s[i]] = 1;//该字符已经出现
}
return ret;
}
求所有的无重复子串
class Solution {
public:
int lengthOfLongestSubstring(string s) {
map<int,int> hs;
int l = 0;
int n = s.size();
int ans = 0;
vector<pair<int,int>> seqs;
for (int r = 0; r < n; ++r) {
int v = s[r];
hs[v]++;
if ( hs[v] == 2) {
while (s[l] != s[r]) {
hs[s[l]]--;
l++;
}
l++;
hs[v]--;
}
int cur_len = r - l + 1;
if ( ans < cur_len)
seqs.clear();
if ( cur_len >= ans )
seqs.push_back( make_pair(l, r));
ans = max( r - l + 1, ans );
}
return ans;
}
};