剑指 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<len(s):
        #r右移,c为即将加入窗口的字符
        c = s[r]
        r += 1
        #更新窗口内的数据
        #TODO
        #print(left,right) #在这里打印区间可以用来debug
        #判断是否移动l指针收缩窗口
        while (窗口内元素不满足条件,满足收缩条件):
            #l左移
            d = s[l]#l为即将被移出窗口的字符
            l += 1
            #更新窗口内的数据
            #TODO
        #此时要在这里更新最优解(窗口内是可行解,更新最优解)
        #TODO
            
    return最优值并处理找不到最优值的情况

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容