• 【leetcode-3】无重复字符的最长子串


    3- 无重复字符的最长子串

    给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

    题目分析

    此题与《剑指offer》48题类似,可以使用动态规划的思想解决。

    • 动态规划

      状态表示:设f(i)为第i个字符为结尾的不包含重复的子字符串的最大长度

      状态转移:当第i个字符没有在i-1个字符中出现时,f(i) = f(i-1)+1;

      当第i个字符在i-1个字符中出现过,首先计算第i个字符和上次出现位置的距离d:如果d小于f(i-1),即之前的最长子字符串中包含该字符,此时截取距离为d的子字符串为新的无重复字符子字符串;如果d大于f(i-1),即之前的最长子字符串不包含该字符,则加1即可

      确定边界:到f(n)结束

      状态转移方程:假设当前的最大长度为maxlength,则有

      maxlength(i) = max(f(i-1), f(i-1)+1)

    代码实现

    实现时与《剑指offer》不同,这里的字符不限于a-z 26个字符。

     
    class Solution:
         def lengthOfLongestSubstring(self, string):
             curLength = 0
             maxLength = 0
             position = {}
             for i in range(len(string)):
                 if string[i] in position.keys():
                     preindex = position[string[i]]
                 else:
                     preindex = -1
                 if preindex <0 or i-preindex > curLength:
                     #没有出现过或者距离大于以i-1为结尾的最大子字符串长度,则f(i) = f(i-1) +1
                     curLength +=1
                 else:
                     if curLength >maxLength:
                         maxLength = curLength
                     #设置新的子字符串的长度
                     curLength = i - preindex
                 position[string[i]] = i
             if curLength > maxLength:
                 maxLength = curLength
             return maxLength
     print(Solution().GetMaxSubStr('arabcacfr'))

    解法2:滑动窗口

    • 使用两个指针表示字符串中的某个子串(左右边界)。

    • 从左向右遍历,左指针逐步向右移动一格,表示开始枚举下一个字符作为起始位置,然后不断向右移动有指针,直到遇到以左指针相同的字符。此时得到的是以左指针字符开始的不包含重复字符的最长子串。

    • 判断重复字符

      常用的数据结构

      • C++

        std::unordered_set

      • Java

        HashSet

      • Python

        set

      • JavaScript

        set

    代码实现

     class Solution:
         def lengthOfLongestSubstring(self, s:str)->int:
             positions = set()
             n = len(s)
             pright, maxlength = 0
             for i in range(n):
                 if !=0:
                     position.remove(s[i-1]) #从新的字符开始计算,去掉之前的
                 # 当right指向的字符在之前的position记录中没有出现,则添加
                 while pright + 1 < n and s[pright+1] not in positions:
                     position.add(s[pright+1])
                     pright +=1
                 # 比较当前字符串与之前统计的最长字符串
                 maxlength = max(maxlength, pright - i + 1)
             return maxlength
  • 相关阅读:
    设计模式:面向对象设计的六大原则 (绝对详细)
    idea创建maven项目速度慢?别急,这有三种方案
    Spring Cloud开发人员如何解决服务冲突和实例乱窜?
    Spring Cloud Zuul的动态路由怎样做?集成Nacos实现很简单
    Spring Boot自定义配置实现IDE自动提示
    阿里注册中心Nacos生产部署方案
    日志排查问题困难?分布式日志链路跟踪来帮你
    zuul集成Sentinel最新的网关流控组件
    YAML中多行字符串的配置方法
    JetBrains 第二轮:再为免费全家桶续命三个月
  • 原文地址:https://www.cnblogs.com/szxyx/p/13329697.html
Copyright © 2020-2023  润新知