给定一个字符串,找出不含有重复字符的最长子串的长度。
示例:
给定 "abcabcbb"
,没有重复字符的最长子串是 "abc"
,那么长度就是3。
给定 "bbbbb"
,最长的子串就是 "b"
,长度是1。
给定 "pwwkew"
,最长子串是 "wke"
,长度是3。请注意答案必须是一个子串,"pwke"
是 子序列 而不是子串。
思路:1.可直接采取暴力解法,借助标准库中的集合,每遍历一次都会得到一个不重复子串的长度,但时间复杂度略高,O(n²)。
2.可想到利用一个滑动窗口,当有重复时,删除掉重复的字符(向前滑动),可利用哈希表来完成(也可以用一个数组代 替,但哈希表更为直观)
代码实现:
1.暴力法
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int n=0;
if(s.length()<=1) //如果字符串为空或者1个,直接返回字符串长度
{
n=s.length();
}
set<char> t;
for(int i=0;i<s.length();i++) //外层遍历循环
{
for(int j=i;j<s.length();j++) //内层遍历循环
{
if(t.count(s[j])) //如果集合中有此字符则跳出循环
{
break;
}
else t.insert(s[j]);
}
n=(n>t.size())?n:t.size(); //外层循环每次判断一下n与集合大小
t.clear(); //清空集合
}
return n;
}
};
2.哈希表法
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int n=0,left=0;
map<char,int> m;
for(int i=0;i<s.length();i++) //每次遍历都会判断左边界限,当有重复时,更新left
{
left=max(left,m[s[i]]); //更新左边界限
m[s[i]]=i+1; //更新哈希表的值
n=max(n,i-left+1); //更新n的值
}
return n;
}
};