3. Longest Substring Without Repeating Characters
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.
3. 无重复字符的最长子串
给定一个字符串,找出其无重复字符的最长子串
例如:
给定
"abcabcbb"
, 结果是 "abc"
, 它的长度是3.
给定
"bbbbb"
, 结果是"b"
, 长度是1.
给定
"pwwkew"
, 结果是 "wke"
, 长度是3. 注意答案应该是一个子串,"pwke"
是一个子序列而不是子串。
思路:
设立两游标,尾巴一直往后走,每遇到新字符就看看当前头尾间有没有出现过这个字符。出现过的话就去掉一个头部,再重复判断。没出现过的话就把这个字符加进来,子串变长1个单位,同时更新最大长度。整体思路好比一个能调节自身的毛毛虫在字符串上伸缩蠕动。
判断头尾间有没有出现过这个字符,这个要用哈希表来解决。由于此处哈希的key是单个字符,所以对c语言来说可以不使用较为复杂的uthash,而是使用长度超过128的数组代替,以char转int后作数组的下标作为key,数组的值作为value。
int lengthOfLongestSubstring(char* s) {
int flag[130] = {0};
char *p1 = s, *p2 = s;
int maxlen = 0, len = 0;
while ((*p1) && (*p2)){
if (flag[*p2]){ //如果尾巴指的字符在子串中
flag[*p1] = 0; //去掉子串中的头部
p1++; //头部后移
len--; //子串变短
}
else{ //如果尾巴指的字符不在子串中
flag[*p2] = 1; //加入子串
p2++; //尾部后移
len++; //子串变长
if (len > maxlen) maxlen = len; //更新最大值
}
}
return maxlen;
}
class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
flag = {} # 字符:存在
p1, p2, lenString = 0, 0, len(s)
maxlen, thislen = 0, 0
while p1 < lenString and p2 < lenString:
if s[p2] in flag: # 如果尾巴所指字符在子串中
del flag[s[p1]] # 删除子串的头部
p1 += 1 # 头部后移
thislen -= 1 # 子串变短
else: # 如果尾巴所指的字符不在子串中
flag[s[p2]] = 1 #加入子串
p2 += 1 # 尾部后移
thislen += 1 # 子串变长
if thislen > maxlen: maxlen = thislen # 更新最大值
return maxlen