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.
代码如下:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
vector<int> dict(256, -1);
int max_len = 0, start_index = -1;
for(int i=0; i<s.length(); ++i){
if(dict[s[i]] > start_index)
start_index = dict[s[i]];
dict[s[i]] = i;
max_len = std::max(max_len, i - start_index);
}
return max_len;
}
};
这道题思路上很明显是需要用到动态规划的,但是怎么用,这就需要和hashmap结合了。既然是字符串,假设都是ascii码字符,一共256个,我们就可以制造一张256个大小的表,表的索引是字符characters,值为每个无重复字串的起始下标,声明vecotr<int> dict(256, -1)。
用法举例:对于字符串“pwwkew"
第一次:出现的字符是p,未操作前dict['p] = -1,那么dict['p'] = 0,此时start_index=-1,dict['p']不大于-1,所以start_index不变还是-1,最大长度就是max_lestart_index = 0 - (-1) = 1。
第二次:出现字符w,同理dict['w] = 1,max_len = 1 - (-1) = 2。
第三次:再次出现w,这时由于未操作前dict['w']是1, 大于start_index(-1),此时更新start_index,也就意味着以前的字串碰见重复字符了,要开始计算新的无重复子串了,新的无重复字串start_index就是前面与之重复的那个字串下标。
因为我们用i-start计算长度,并没有+1,所以实际上start必须是无重复字串起始前一个位置,恰好剔除前一个重复元素。
我们开场设定的start_Index的初值为-1也是为了这个目的。现在start_index=1,i=2,max_len = 2 - 1 = 1,符合要求,我们当前无重复字串只包含有一个"w"。
第四次:出现k,未操作前dict['k'] = -1,不大于start_index,说明还在那个无重复字串扩充长度过程中,start_index不变,那么dict['k] = 3,max_len现在是i-start_index = 3 - 1 = 2,长度为2,即“wk"。
后续就不必再说了,类似的。