给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这道题看到后第一反映是采用快慢指针进行遍历,也就是最原始的暴力破解法。
1.暴力破解:采用left,right两个指针来遍历整个字符串,在每次循环移动left时都需要遍历一遍从left到right之间的字符是否有重复,没有则right++,知道遇见重复或者right到头为止。浪费时间最多的就在于查找重复字符串的部分。这里还可以再加一个对right== size -1的判断跳出循环,进一步优化。
2.类似暴力破解:和第一种方法相比就是采用了c++的hash表,大大的缩短了查找重复字符的时间。其余部分和第一种方法几乎一样。也是两层循环不断更新left和right,循环次数相同。还是得益于高级语言的特性,否则自己写个hash还是很有难度的。
3. 优化版暴力破解:和前两种方法采用的相同的遍历原理,但是采用了map,记录了字符的同时也记录了字符的位置,采用临时变量记录当前的字符串长度,然后和两个重复字符之间的长度取最小值,来不断求取字符串的长度(使用abba推导一下即可明白求取原理)。这种方法只需要一层循环,相比与第二种方法减少了外层循环的一些操作以及查询hash表的次数。
这道题与另一道题有很大的相似之处,背后的原理很相似:
https://blog.youkuaiyun.com/weixin_41777654/article/details/124775630?spm=1001.2014.3001.5502
class Solution {
public:
int lengthOfLongestSubstring(string s) {
#if 0
int max_len = 0;
int left = 0, right = 0;
int matched = 0;
while (left < s.size() && max_len < (s.size() - left))
{
while(right < s.size())
{
for (int i = left; i < right; i++) // 如果只有一个字符for循环不执行, matched = 0, max_len = 1
{
if (s[i] == s[right])
{
matched = 1;
}
}
if (matched == 0)
{
max_len = max(right - left + 1, max_len);
right++;
}
else
{
matched = 0;
break;
}
}
left++;
}
return max_len;
#endif
#if 0
int max_len = 0;
unordered_set<char> child_str;
int left = 0, right = 0;
while ((left < s.size()) && (max_len < (s.size() - left)))
{
if (left != 0)
{
child_str.erase(s[left - 1]);
}
while (right < s.size() && !child_str.count(s[right]))
{
child_str.insert(s[right]);
max_len = max(right - left + 1, max_len);
right++;
}
left++;
}
return max_len;
#endif
int len = s.size();
//滚动数代替dp数组
int res = 0, temp = 0;
unordered_map<char, int> hashtable;
for (int i = 0; i < len; i++)
{
temp++;
if (hashtable.count(s[i]) != 0)
{
temp = min(temp, i - hashtable[s[i]]);
}
hashtable[s[i]] = i;
res = max(res, temp);
}
return res;
}
};