zoukankan      html  css  js  c++  java
  • 386. 最多有k个不同字符的最长子字符串

    386. 最多有k个不同字符的最长子字符串

    中文English

    给定字符串S,找到最多有k个不同字符的最长子串T

    样例

    样例 1:

    输入: S = "eceba" 并且 k = 3
    输出: 4
    解释: T = "eceb"
    

    样例 2:

    输入: S = "WORLD" 并且 k = 4
    输出: 4
    解释: T = "WORL" 或 "ORLD"

    挑战

    O(n) 时间复杂度

    输入测试数据 (每行一个参数)如何理解测试数据?

     第一种写法:(同向型双向指针)

    class Solution:
        """
        @param s: A string
        @param k: An integer
        @return: An integer
        """
        def lengthOfLongestSubstringKDistinct(self, s, k):
            # write your code here
            if len(s) <= k: return len(s)
            
            array = []
            l, max_value = len(s), 0
            count = 0 
            j = 0
            
            #主指针,缩小区间,维持区间内都符合条件
            for i in range(l):
                j = i
    
                #一定要在count <= k里面,直到等于k的时候才可以,不然会出现刚好到k的情况,立马跳出循环。这样的话就不是取到最大长度了,例如j,j,j
                #刚好出现第一个j新字符,就跳出循环,后面就不在append到array里面了
                while count <= k and j < l:#count = k 重要,否则无法更新到最长相同字符串那里
                    if s[j] not in array:
                        count += 1 
                    array.append(s[j])
                    j += 1 
    
                    if (count <= k):
                        max_value = max(j - i, max_value)
                
                #缩小区间
                count = 0 
                array = []
    
            return max_value

    注:lintcode未通过,时间复杂度问题,待优化

    优化版本一:通过字典的方式(外面缩减区间,里面增大区间)

    class Solution:
        """
        @param s: A string
        @param k: An integer
        @return: An integer
        """
        def lengthOfLongestSubstringKDistinct(self, s, k):
            # write your code here
            if len(s) <= k: return len(s)
            
            counter = {}
            l, max_value = len(s), 0
            j = 0
            
            #主指针,缩小区间,维持区间内都符合条件
            for i in range(l):
                #一定要在count <= k里面,直到等于k的时候才可以,不然会出现刚好到k的情况,立马跳出循环。这样的话就不是取到最大长度了,例如j,j,j
                #刚好出现第一个j新字符,就跳出循环,后面就不在append到array里面了
                while len(counter) <= k and j < l:
                    counter[s[j]] = counter.get(s[j], 0) + 1
                    j += 1 
                    if (len(counter) <= k):
                        max_value = max(j - i, max_value)
    
                #缩小区间
                counter[s[i]] -= 1 
                if counter[s[i]] == 0:
                    del counter[s[i]]
                
            return max_value

    优化版本二(外面增大区间,里面缩减区间,一直缩减到符合最长不同字符为k截止,跳出循环)

    class Solution:
        """
        同向型双指针
        """
        def lengthOfLongestSubstringKDistinct(self, s, k):
            #维持区间在满足最长不同字符k长度左右
            if not s: return 0 
    
            counter = {}
            l = len(s)
            max_res = 0
            j = 0
    
            #增大区间,主指针
            for i in range(l):
                counter[s[i]] = counter.get(s[i], 0) + 1
                
                #缩小区间,维持最长不同字符为k,如果大于k,则开始缩减,注意大于即可,一直到等于便可以跳出循环
                while len(counter) > k and j < l:
                    counter[s[j]] -= 1
                    if counter[s[j]] == 0:
                        del counter[s[j]]
                    
                    #可能存在多个相同的,也会一直缩减到不同字符长度k截止
                    j += 1
                
                #在这里已经是符合条件的k长度了,所以可以取最大值
                max_res = max(max_res, i - j + 1)
            
            return max_res
  • 相关阅读:
    vivify.css动画效果
    Vue实现左侧可伸缩
    移动端web开发理想视口及normalize.css
    vue的transition标签配合animate.css与vivify.css使用的方式
    说说godaddy
    选择比努力更重要
    从开发讲起,组织松散化,社会向上
    什么上的人能成
    Azure和aws使用对比
    MSBuild
  • 原文地址:https://www.cnblogs.com/yunxintryyoubest/p/13193490.html
Copyright © 2011-2022 走看看