这是一道十分经典的题目,但对与我这样一个入门级的小白来说,做出来并理解它也花了不少的功夫啊。
题目:
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
例:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
这道题我第一次见是在我们学校的一次考试上,当时只能想到暴力法,看网上很多人的暴力法,最多的也不过是O(N^3),
但是我当时却写了O(N^4),(手动哭泣)。
后来在Leetcode上面又看到了这道题
(https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/)
于是下决心来研究一下,终于弄个明白了。
这里我主要介绍两个算法(暴力法就不说辽~)
1. 滑动窗口法
先选定start何end两个指针(这里的指针代表位置),均从第一个字符开始,向后移动end,如果end和从start到end这段的字串的每一个字符都不相同,则继续向后移,直至出现相同或者end到达字符串末尾,并随时记录长度。
若出现相等,(重点来了,敲黑板了),假设是位置i和end相等了,这时我们就要先将start移动到i+1的位置。
为什么要这么做呢,我们来想一下,这种情况会不会漏掉什么?现在是i和end重了,现在无论我们把start放在start到i的任何一个位置,都改变不了冲突的事实,所以我们就直接将start放在i+1的位置上来重新弄这个字串。
记录下这个新字符串的长度,然后将新串的长度与原来的长度比较,选择下较长的那个。并继续循环,最后输出的就是最长的长度了。
基本的逻辑已经讲完了,下面我们来看代码和一些细节。
class Solution
{
public:
int lengthOfLongestSubstring(string s)
{
int start = 0, end = 0, length = 0, maxlen = 0;
while(s[end] != 0)
{
for (int index = start; index < end; index++)
{
if (s[end] == s[index])
{
start = index + 1;//一定要先移动,再计算长度,因为计算的是新串的长度。
length = end - start; //这里长度会少一个,不过下面补上
break;
}
}
end++;
length++;//end移位时就加一个长度,顺便也补上了特殊情况差的长度了
maxlen = maxlen > length?maxlen:length;
}
return maxlen;
}
};
基本细节都再代码上写出来了。
2. 哈希表法
哈希表法的基本思路和方法一差不多,差别就在遍历字串时采用了哈希表,这样就把遍历的时间复杂度降到了O(1)。
实现方法是用unordered_map。
头文件#include<unordered_map>
它的key就是用哈希表存储的,至于哈希表的对应关系则已经被封装了,我们看不见,但是并不影响我们使用。
用key来存储字符,用T来存储字符的位置。
下面直接上代码
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int start = 0,end = 0,maxlen = 0,length = 0;
unordered_map<char, int> hash;//创建hashmap
while(s[end] != 0){
if(hash.find(s[end]) != hash.end() && hash[s[end]] >= start){
//后一个比较是为了防止出现过了,但已经不再当前子串中的产生bug
start = hash[s[end]] + 1;
length = end-start;
}
hash[s[end]] = end;//记得实时更新哈希表
end++;
length++;
maxlen = maxlen > length?maxlen:length;
}
return maxlen;
}
};
唯一要注意的就是
hash[s[end]] >= start
这个部分,为什么要加上这个部分呢?
举个例子
adbcbd
第一个冲突的是b所以start是放到b,这时如果end到了字符d的话,没有这一部分的话,前面已经有d了,如果不加这个判定,则d已经再哈希表中了,会产生错误,所以一定要加上这一条。
呼~
以上就是这道题的解法了,溜了溜了…
来源:CSDN
作者:直男straight
链接:https://blog.csdn.net/weixin_44783556/article/details/104416944