自学内容网 自学内容网

无重复字符的最长子串

给定一个半角英文字符串,找出无重复字符的最长子串长度。


(笔记模板由python脚本于2024年04月11日 23:19:44创建,本篇笔记适合初通Python,熟悉六大基本数据(str字符串、int整型、float浮点型、list列表、tuple元组、set集合、dict字典)的coder翻阅)


【学习的细节是欢悦的历程】


  自学并不是什么神秘的东西,一个人一辈子自学的时间总是比在学校学习的时间长,没有老师的时候总是比有老师的时候多。
            —— 华罗庚


等风来,不如追风去……


给定一个半角英文字符串
无重复字符最长子串
(找出无重复字符的最长子串长度)


本文质量分:

96 96 96

本文地址: https://blog.csdn.net/m0_57158496/article/details/137657295

CSDN质量分查询入口:http://www.csdn.net/qc


目 录

  • ◆ 无重复字符的最长子串
    • 1、题目描述
    • 2、算法解析
      • 2.1 `for`循环嵌套遍历
      • 2.2 我的算法优化
      • 2.3 力扣题解大神算法
    • 3、代码效率测试
      • 3.1 代码力扣提交信息
      • 3.2 本地代码运行用时测试
    • 4、完整源码(Python)


◆ 无重复字符的最长子串


1、题目描述




回页目录


2、算法解析


  我最能想到的本题目解决方案是用“循环嵌套”,我用的for嵌套。代码写完发现,循环次数太多,用时太久。试着优化成单层循环,剔除了大量不必要的遍历,缩短了一半的时间。后来习读大神的“双指针”代码,力扣提交,样例用时比我“优化”代码用时<font size=> 1 / 3 1/3 1/3还少!


2.1 for循环嵌套遍历


  • 代码解析

      一般常规解法:双层for嵌套遍历字符串。外层控制字符串起点,内层搜索非重复字符串并记录最大长度。此法缺点循环次数太多

Python代码


class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        n = len(s)
        if n < 2: return n
        
        l = 0 # 非重复字母长度初值。
        ss = '' # 搜索到的非重复字符串初值。

        for i in range(n):
            for j in range(i, n):
                if s[j] not in ss: ss += s[j]
                else:
                    if len(ss) > l: l = len(ss)
                    ss = '' # 非重复字符串变量清零,方便存储下一个非重复字符串。
                    break
                
        return l



回页目录


2.2 我的算法优化


  • 代码解析

      仔细审验上段代码,用if控制内存循环遍历到有字符重复时,记录无重复字符串子串长度后结束循环,剔除不必要的循环遍历。

Python代码


class Solution2:
    def lengthOfLongestSubstring(self, s: str) -> int:
        n = len(s)
        if n < 2: return n
        a = l = 0

        for i in range(n):
            ss = s[a:i]
            local = s[i]
            n = len(ss) 
            if local in ss:
                l = n if n > l else l

                while 1:

                    if s[i-1] == local:
                        a = i
                        break 
                        
                    i -= 1
        
        n = len(s[a:])        
        return n if n > l else l



回页目录


2.3 力扣题解大神算法


  • 大神代码I

Python代码


class Solution3: # 力扣题解大神代码I
    def lengthOfLongestSubstring(self, s: str) -> int:
        if not s:return 0
        left = 0
        lookup = set()
        n = len(s)
        max_len = 0
        cur_len = 0
        for i in range(n):
            cur_len += 1
            while s[i] in lookup:
                lookup.remove(s[left])
                left += 1
                cur_len -= 1
            if cur_len > max_len:max_len = cur_len
            lookup.add(s[i])
        return max_len


  • 大神代码II


Python代码


class Solution4: # 力扣题解大神代码II
    def lengthOfLongestSubstring(self, s: str) -> int:
        dic, res, i = {}, 0, -1
        for j in range(len(s)):
            if s[j] in dic:
                i = max(dic[s[j]], i) # 更新左指针 i
            dic[s[j]] = j # 哈希表记录
            res = max(res, j - i) # 更新结果
        return res



回页目录


3、代码效率测试


3.1 代码力扣提交信息


  • 代码力扣提交截屏图片

    一般循环遍历代码
    在这里插入图片描述

    优化算法单层循环代码
    在这里插入图片描述

    大 神 代 码 大神代码

    I I I.
    在这里插入图片描述

    I I II II.
    在这里插入图片描述



回页目录


3.2 本地代码运行用时测试


  • 代码运行效果截屏图片
    在这里插入图片描述

代码调用


if __name__ == '__main__':
    s = 'ACaA5abababc 5dabcj5gh'
    n = 100000
    print(f"\n试码用例字符串:\n{s = }\n\n运行代码{n}次用时:")

    s1 = Solution()
    t = time()
    for i in range(n):
       s1.lengthOfLongestSubstring(s)
    
    print(f"\n常规写法:\n{s1.lengthOfLongestSubstring(s) = }")
    print(f"{time()-t:.2f}s")
    
    
    s2 = Solution2()
    t = time()
    for i in range(10000):
       s2.lengthOfLongestSubstring(s)
    
    print(f"\n优化算法:\n{s2.lengthOfLongestSubstring(s) = }")
    print(f"{time()-t:.2f}s")

    s3 = Solution3()
    t = time()
    for i in range(10000):
       s3.lengthOfLongestSubstring(s)
    
    print(f"\n力扣题库大佬题解代码:\n{s3.lengthOfLongestSubstring(s) = }")
    print(f"{time()-t:.2f}s")



回页目录


4、完整源码(Python)

(源码较长,点此跳过源码)

#!/sur/bin/nve python
# coding: utf-8
from time import time


class Solution4: # 力扣大神代码II
    def lengthOfLongestSubstring(self, s: str) -> int:
        dic, res, i = {}, 0, -1
        for j in range(len(s)):
            if s[j] in dic:
                i = max(dic[s[j]], i) # 更新左指针 i
            dic[s[j]] = j # 哈希表记录
            res = max(res, j - i) # 更新结果
        return res



# 一般常规解法:双层for嵌套遍历字符串。外层控制字符串起点,内层搜索非重复字符串并记录最大长度。此法缺点:循环次数太多。
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        n = len(s)
        if n < 2: return n
        
        l = 0 # 非重复字母长度初值。
        ss = '' # 搜索到的非重复字符串初值。

        for i in range(n):
            for j in range(i, n):
                if s[j] not in ss: ss += s[j]
                else:
                    if len(ss) > l: l = len(ss)
                    ss = '' # 非重复字符串变量清零,方便存储下一个非重复字符串。
                    break
                
        return l


class Solution2:
    def lengthOfLongestSubstring(self, s: str) -> int:
        n = len(s)
        if n < 2: return n
        a = l = 0

        for i in range(n):
            ss = s[a:i]
            local = s[i]
            n = len(ss) 
            if local in ss:
                l = n if n > l else l

                while 1:

                    if s[i-1] == local:
                        a = i
                        break 
                        
                    i -= 1
        
        n = len(s[a:])        
        return n if n > l else l


class Solution3: # 力扣大神代码I
    def lengthOfLongestSubstring(self, s: str) -> int:
        if not s:return 0
        left = 0
        lookup = set()
        n = len(s)
        max_len = 0
        cur_len = 0
        for i in range(n):
            cur_len += 1
            while s[i] in lookup:
                lookup.remove(s[left])
                left += 1
                cur_len -= 1
            if cur_len > max_len:max_len = cur_len
            lookup.add(s[i])
        return max_len


if __name__ == '__main__':
    s = 'ACaA5abababc 5dabcj5gh'
    n = 100000
    print(f"\n试码用例字符串:\n{s = }\n\n运行代码{n}次用时:")

    s1 = Solution()
    t = time()
    for i in range(n):
       s1.lengthOfLongestSubstring(s)
    
    print(f"\n常规写法:\n{s1.lengthOfLongestSubstring(s) = }")
    print(f"{time()-t:.2f}s")
    
    
    s2 = Solution2()
    t = time()
    for i in range(10000):
       s2.lengthOfLongestSubstring(s)
    
    print(f"\n优化算法:\n{s2.lengthOfLongestSubstring(s) = }")
    print(f"{time()-t:.2f}s")

    s3 = Solution3()
    t = time()
    for i in range(10000):
       s3.lengthOfLongestSubstring(s)
    
    print(f"\n力扣题库大神题解代码I:\n{s3.lengthOfLongestSubstring(s) = }")
    print(f"{time()-t:.2f}s")

    s4 = Solution4()
    t = time()
    for i in range(10000):
       s4.lengthOfLongestSubstring(s)
    
    print(f"\n力扣题库大神题解代码II:\n{s4.lengthOfLongestSubstring(s) = }")
    print(f"{time()-t:.2f}s")



回页首


上一篇:  插值字符串格式代码中的“!”(Python)(读到插值字符串格式化代码中有“!”,进行了一番探究,了解了其中的一点“隐秘”,在此共享)
下一篇: 



我的HOT博:

  本次共计收集 311 篇博文笔记信息,总阅读量43.82w。数据于2024年03月22日 00:50:22完成采集,用时6分2.71秒。阅读量不小于6.00k的有 7 7 7篇。


推荐条件 阅读量突破6.00k
(更多热博,请点击蓝色文字跳转翻阅)

  • 截屏图片
    在这里插入图片描述
      (此文涉及ChatPT,曾被csdn多次下架,前几日又因新发笔记被误杀而落马。躺“未过审”还不如回收站,回收站还不如永久不见。😪值此年底清扫,果断移除。留此截图,以识“曾经”。2023-12-31)



回页首


老齐漫画头像

精品文章:

来源:老齐教室


Python 入门指南【Python 3.6.3】


好文力荐:


CSDN实用技巧博文:



原文地址:https://blog.csdn.net/m0_57158496/article/details/137657295

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!