Leetcode算法——3、最长无重复子串问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HappyRocking/article/details/82289065

题目

Given a string, find the length of the longest substring without repeating characters.

给定一个字符串,找到最长的不包含重复字符的子字符串的长度。

示例:
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.

思路

1、暴力求解

双重循环,遍历所有的子串,判断其是否不包含重复字符,并找到最长的子串。
双重循环的复杂度为 n 2 ,判断是否包含重复字符的复杂度为 n ,因此算法整体的复杂度为 O ( n 3 )

2、动态规划

维护一个词典,里面存放着已经扫描过的字符和位置。
每扫描到一个新的元素,判断这个元素是否在词典中,如果在,说明这个元素开始重复了,那这两个位置之间的子串为无重复子串,需要加入到候选列表中。同时,当前子串的起始位置变为第一次出现这个元素的位置的后面一个,这样可以保证尽可能找到不重复且最长的子串。

python实现

# -*- coding: utf-8 -*-

def lengthOfLongestSubstring(s):
    '''
    动态规划。
    维护一个数存放最大长度。从左向右扫描,如果扫描到了重复字符,则比较现在的子字符串长度与最大长度的大小,然后将子字符串起始位置移到第一次出现此字符的后面,继续扫描。
    '''
    max_len = 0 # 存放最大长度
    start_idx = 0 # 子字符串的起始位置
    scaned_dict = dict() # 记录每次扫描到的字符,key=char,value=index
    for i in range(0, len(s)):

        # 如果字符存在于字典中,且位置是在起始位置的右边,说明遇到了重复字符
        if s[i] in scaned_dict and scaned_dict[s[i]] >= start_idx: 
            max_len = max(max_len, i - start_idx) # 统计重复字符之前的最长字符串
            start_idx = scaned_dict[s[i]] + 1 # 将起始位置修改为重复字符第一次出现的位置的右邻

        scaned_dict[s[i]] = i # 记录当前字符的位置

    max_len = max(max_len, len(s) - start_idx) # 这一句必不可少
    return max_len

if '__main__' == __name__:
    s_list = ["abcabcbb","bbbbb","pwwkew"," "]
    for s in s_list:
        print(f'输入{s},输出{lengthOfLongestSubstring(s)}')



猜你喜欢

转载自blog.csdn.net/HappyRocking/article/details/82289065