leetcode3. 无重复字符的最长子串 medium
题目描述:
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
解题思路:
可以建立一个HashMap,建立每个字符和其最后出现位置之间的映射,然后我们需要定义两个变量res和left,其中res用来记录最长无重复子串的长度,left指向以上一个字符为结尾的子串中最长无重复子串的起始位置的前一个,由于是前一个,所以初始化就是-1,然后我们遍历整个字符串,对于每一个遍历到的字符,如果该字符已经在HashMap中存在了,并且如果其映射值大于left的话,那么更新left为当前映射值。然后映射值更新为当前坐标i,这样保证了left始终为当前边界的前一个位置,然后计算窗口长度的时候,直接用i-left即可,用来更新结果res。
代码:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_map<char, int> hash; // 保存已经遍历到的字符 最近一次出现的下标
int res = 0;
for (int i = 0, j=0; j < s.size(); ++j) // i,j 维护当前左右边界
{
char c = s[j];
if (hash.count(c) && hash[c] >= i)
i = hash[c]+1;
hash[c] = j;
res = max(res, j-i+1);
}
return res;
}
};
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s.size()<2)
return s.size();
unordered_map<char,int> dict; // 保存已经遍历到的字符 最近一次出现的下标
int left=-1; //上一个字符为尾的 最长无重复字符子串开始位置的前一个位置
int res=0; // 不重复字符的最长子串的长度
for(int i=0;i<s.size();++i){
if(dict.count(s[i]) && dict[s[i]]>left) // 如果之前有这个字符,且位置大于left
left=dict[s[i]]; // 更新left
dict[s[i]]=i; // 更新s【i】位置
res= max(res,i-left); // 更新res
}
return res;
}
};
// 代码2
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s.size()<2)
return s.size();
unordered_map<char,int> hash;
int res=0;
// 双指针
for(int i=0,j=0;i<s.size();++i){
hash[s[i]]++;
while(hash[s[i]]>1)
hash[s[j++]]--;
res = max(res,i-j+1);
}
return res;
}
};