标签:结构 etc return ram vector 查找 acea 长度 note
1. 题目(来自leetcode):
Given a string, find the length of the longest substring without repeating characters.
Examples:
Given "abcabcbb"
, the answer is "abc"
, which the length is 3.
Given "bbbbb"
, the answer is "b"
, with the length of 1.
Given "pwwkew"
, the answer is "wke"
, with the length of 3. Note that the answer must be a substring, "pwke"
is a subsequence and not a substring.
2. 解题思路:
以abgaceadbb为例:
1. 从a开始直到遇到第4个元素为重复的a,中间走过的元素可以确定是不重复的,因此可以不用重新遍历,只需排除第一个a,以b为头,从第5个元素继续往前查看。
2. 一直到第7个元素,发现与第4个元素a重复,目前我们得到的最长不重复的字符串长度为5。由于第4个元素和第7个元素a重复,因此,以目前的头b与第4个元素a之间任何一个元素作为开头,都不会得到更长的字符串,因此,以第4个元素后的c为头,继续从第8个元素往前查看。
3.直到查看到字符串的末端。
因此这个算法为,将字符串的第一个元素作为开头,向前遍历字符串,每次查看遍历到的字符是否在目前的子字符串中,若存在,则将这个子字符串中重复的字符的后一个字符作为新的头,继续遍历。在这过程中不断更新最长子字符串的长度。直到遍历完成。
这个算法的复杂度为O(n),因为只需遍历一次字符串。
3. 实现:
我这次试图用C++去实现这个算法,但是在实现的过程中,我想要找到一个合适的数据结构,这个数据结构要满足以下条件:
(1)这个数据结构用来记录目前的子字符串,因此要方便查询是否已经存了某个元素。
(2)子字符串的字符需要按顺序存入,因为在查找到重复字符后,需要把重复字符前包括重复字符的元素都删除。
根据这个想法,我尝试了vector,stack,map等数据结构,相对来说都比较麻烦。这里就不放上来了。
Leetcode上的网友lightmark给出了一个简洁的C++代码,我感觉非常的强大,至少我实在想不出可以这样实现,因此我放上来分析一下:
int lengthOfLongestSubstring(string s) {
vector<int> dict(256, -1);
int maxLen = 0, start = -1;
for (int i = 0; i != s.length(); i++) {
if (dict[s[i]] > start)
start = dict[s[i]];
dict[s[i]] = i;
maxLen = max(maxLen, i - start);
}
return maxLen;
}
1. 第一行创建了一个大小为256的vector并且全部元素初始化为-1。(256是为了确保,这个vector的大小能够包含所有字符的ASCII码)
2. maxLen用来记录目前最长字符串的长度,start用来记录当前子字符串的第一个元素的位置(准确来说是位置前一位)。
3. 从字符串第一个元素开始遍历。
4. if判断是这个代码的重点,需要和if后面的语句一起看。每一个字符若直接转换到int将会得到他们对应的ASCII码,如 a得到97。因此dict[s[i]]是以每个字符的ASCII码作为索引来得到字符对应的位置。在这个代码中每次遍历到新字符,会用dict[s[i]]来查询上一次遇见这个字符的位置,-1为从未遇见过,若dict[s[i]]>start则意味着,上次遇到这个字符的位置在目前的子字符串第一个元素后,因此是重复字符,所以start = dict[s[i]] 将新的开头指向了这个重复字符的位置。从而继续遍历。
Longest Substring Without Repeating Characters
标签:结构 etc return ram vector 查找 acea 长度 note
原文地址:https://www.cnblogs.com/lynn-code/p/8924076.html