剑指 Offer 48. 最长不含重复字符的子字符串

请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。

示例 1:

输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

解题:
这里我们的字典index_dict性质改变,不只用来记录cur_str中的所有字符,而是遍历到当前位置cur_index后之前所有s中出现过的字符及其距离cur_index最近的下标。这样就要求我们不能随意更新cur_str的开始位置start_index,这时,我们更新start_index不仅需要当前字符在index_dict中出现过,位置为prev_index,而且需要保证出现的位置在cur_str中,这就要求上次出现位置prev_index<当前字符串的开始位置cur_index,省去了删除字典元素的步骤。

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        if s is None and len(s) == 0:
            return 0
        max_len = start_index = 0
        index_dict = {}

        for i in range(len(s)):
            cur_str = s[i]
            if cur_str in index_dict and index_dict[cur_str] >= start_index:
                start_index = index_dict[cur_str] + 1
            cur_len = i - start_index + 1
            index_dict[cur_str] = i
            max_len = max(max_len, cur_len)
        return max_len


if __name__ == "__main__":
    sc = Solution()
    sccd = "bacabcdefbb"
    print(sc.lengthOfLongestSubstring(sccd))
i, cur_str: 0 b
cur_len: 1
index_dict: {'b': 0}
max_len: 1
i, cur_str: 1 a
cur_len: 2
index_dict: {'b': 0, 'a': 1}
max_len: 2
i, cur_str: 2 c
cur_len: 3
index_dict: {'b': 0, 'a': 1, 'c': 2}
max_len: 3
i, cur_str: 3 a
index_dict[cur_str]: 1
start_index: 2
cur_len: 2
index_dict: {'b': 0, 'a': 3, 'c': 2}
max_len: 3
i, cur_str: 4 b
cur_len: 3
index_dict: {'b': 4, 'a': 3, 'c': 2}
max_len: 3
i, cur_str: 5 c
index_dict[cur_str]: 2
start_index: 3
cur_len: 3
index_dict: {'b': 4, 'a': 3, 'c': 5}
max_len: 3
i, cur_str: 6 d
cur_len: 4
index_dict: {'b': 4, 'a': 3, 'c': 5, 'd': 6}
max_len: 4
i, cur_str: 7 e
cur_len: 5
index_dict: {'b': 4, 'a': 3, 'c': 5, 'd': 6, 'e': 7}
max_len: 5
i, cur_str: 8 f
cur_len: 6
index_dict: {'b': 4, 'a': 3, 'c': 5, 'd': 6, 'e': 7, 'f': 8}
max_len: 6
i, cur_str: 9 b
index_dict[cur_str]: 4
start_index: 5
cur_len: 5
index_dict: {'b': 9, 'a': 3, 'c': 5, 'd': 6, 'e': 7, 'f': 8}
max_len: 6
i, cur_str: 10 b
index_dict[cur_str]: 9
start_index: 10
cur_len: 1
index_dict: {'b': 10, 'a': 3, 'c': 5, 'd': 6, 'e': 7, 'f': 8}
max_len: 6
6

其实,这种题目最好用的通用方法就是 滑动窗口。

def slidingWindow(s):
    #初始化左指针和右指针(左闭右开区间)
    l,r = 0,0
    while r

你可能感兴趣的:(剑指 Offer 48. 最长不含重复字符的子字符串)