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

本文介绍了一种寻找字符串中最长无重复字符子串的方法,包括暴力求解和动态规划两种策略。通过维护一个词典来跟踪已扫描的字符及其位置,确保找到的是最长且不含重复字符的子串。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

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、暴力求解

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

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)}')



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值