【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

 

posted @ 2020-07-17 14:14  szxyx  阅读(188)  评论(0编辑  收藏  举报