Longest Substring with At Most K Distinct Characters

要点:要搞清楚At Most Two Distinct和Longest Substring Without Repeating Characters (No Repeating)的区别:前者的sliding window里只有2个char,但是可以任意重复。而后者可以有任意多个char但是任何char都不能有重复。

  • 所以解法上前者的hashset只有2个元素,而后者需要把所有distinct的元素放到hashset里。而前者因为只有当不在hashset中的元素才可能考虑更新hashset,而后者是有当前元素在hashset里更新。
  • 推广到k,
    • At Most K Distinct要把k个元素中最后一次出现(最右)最靠左的那个去掉,所以要不断更新最右边界,At Most K Repeating因为新元素在hashset中,所以去掉的只能是该元素,只是k扩展到要记录重复的元素个数是否到k才启动。
    • At Most K Distinct还有用count的方法:把集中检查边界分布到从左向右每个元素减少count,最先count减少到0的就是最左。而At Most K Repeating因为只去掉一个元素,没有这个方法。

要点:

  • 是对longest substring without repeating characters这题另一种思路的扩展。no repeating这题是用map存当前sliding window的字符,下一个char不能出现在map中。而distinct这题是下一个不能是没有在map中的(除非map中只有一个or <k个)。
  • k个中选哪个取代?显然k个字符中最后出现中最靠左的字符是所选。这样能保证当前sliding window中的local maxLen
  • 上面的方法每次新字符都要遍历k个在map中的字符,整体时间是O(n)*O(k)。另一种方法更类似no repeating的方法。直接从sliding window左边开始pop直到某个元素count==0(所以map中记录count)。其实也是找到最后出现的最靠左字符。

错误点:

  • start的更新在清楚左边界的loop内,如果没有进入这个清除环节,不需要更新start
  • start的更新在leftMost的+1位置
  • count version不用检查>0,因为在map中的都是如此
  • count version:注意start是index,umap[s[start]]
  • count version: 初始map中的count value是1而不是0
  • count version: 别忘了新元素进map(主要是光想着del key了)

https://repl.it/CaiH (map loop)
https://repl.it/CaiT/1 (k, count)
https://repl.it/CqmA (Two, use char1, char2 variables)

class Solution(object):
    def lengthOfLongestSubstringKDistinct(self, s, k):
        """
        :type s: str
        :type k: int
        :rtype: int
        """
        n = len(s)
        maxLen = 0
        umap = {}
        start = 0
        for i in xrange(n):
            if s[i] not in umap and len(umap)>=k:
                leftMost = n
                rmChar = None
                for c in umap:
                    if umap[c]<leftMost:
                        leftMost = umap[c]
                        rmChar = c
                del umap[rmChar]
                start = leftMost+1 # error 1: start should be set inside update condition
                                   # error 2: start index: next of leftMost
            umap[s[i]]=i

            if i-start+1>maxLen:
                maxLen = i-start+1
            #print i,start,maxLen,umap
        return maxLen

sol = Solution()
print sol.lengthOfLongestSubstringKDistinct("aabbcc", 1)
print sol.lengthOfLongestSubstringKDistinct("aabbcc", 2)
print sol.lengthOfLongestSubstringKDistinct("aabbcc", 3)
print sol.lengthOfLongestSubstringKDistinct("eceba", 2)
        
# Given a string, find the length of the longest substring T that contains at most k distinct characters.

# For example, Given s = “eceba” and k = 2,

# T is "ece" which its length is 3.

# Hide Company Tags Google
# Hide Tags Hash Table String
# Hide Similar Problems (H) Longest Substring with At Most Two Distinct Characters

class Solution(object):
    def lengthOfLongestSubstringKDistinct(self, s, k):
        """
        :type s: str
        :type k: int
        :rtype: int
        """
        umap = {}
        if k==0: return 0
        longest, start = 0,0
        for i in xrange(len(s)):
            # print "it=", i,umap,len(umap)
            if s[i] in umap:
                umap[s[i]]+=1
            elif len(umap)<k:
                umap[s[i]]=1 # error 1: should be 1, not 0
            else:
                umap[s[i]]=1 # error 2: don't forget to put myself into
                while start<i:
                    c = s[start]
                    start+=1
                    umap[c]-=1
                    if not umap[c]:
                        del umap[c]
                        break
            longest = max(longest, i-start+1)
        return longest

sol = Solution()
assert sol.lengthOfLongestSubstringKDistinct("eceba", 2)==3
        

边工作边刷题:70天一遍leetcode: day 71-1的更多相关文章

  1. 边工作边刷题:70天一遍leetcode: day 71

    Longest Substring with At Most Two Distinct Characters # Given a string, find the length of the long ...

  2. 边工作边刷题:70天一遍leetcode: day 89

    Word Break I/II 现在看都是小case题了,一遍过了.注意这题不是np complete,dp解的time complexity可以是O(n^2) or O(nm) (取决于inner ...

  3. 边工作边刷题:70天一遍leetcode: day 77

    Paint House I/II 要点:这题要区分房子编号i和颜色编号k:目标是某个颜色,所以min的list是上一个房子编号中所有其他颜色+当前颜色的cost https://repl.it/Chw ...

  4. 边工作边刷题:70天一遍leetcode: day 78

    Graph Valid Tree 要点:本身题不难,关键是这题涉及几道关联题目,要清楚之间的差别和关联才能解类似题:isTree就比isCycle多了检查连通性,所以这一系列题从结构上分以下三部分 g ...

  5. 边工作边刷题:70天一遍leetcode: day 85-3

    Zigzag Iterator 要点: 实际不是zigzag而是纵向访问 这题可以扩展到k个list,也可以扩展到只给iterator而不给list.结构上没什么区别,iterator的hasNext ...

  6. 边工作边刷题:70天一遍leetcode: day 101

    dp/recursion的方式和是不是game无关,和game本身的规则有关:flip game不累加值,只需要一个boolean就可以.coin in a line II是从一个方向上选取,所以1d ...

  7. 边工作边刷题:70天一遍leetcode: day 1

    (今日完成:Two Sum, Add Two Numbers, Longest Substring Without Repeating Characters, Median of Two Sorted ...

  8. 边工作边刷题:70天一遍leetcode: day 70

    Design Phone Directory 要点:坑爹的一题,扩展的话类似LRU,但是本题的accept解直接一个set搞定 https://repl.it/Cu0j # Design a Phon ...

  9. 边工作边刷题:70天一遍leetcode: day 71-3

    Two Sum I/II/III 要点:都是简单题,III就要注意如果value-num==num的情况,所以要count,并且count>1 https://repl.it/CrZG 错误点: ...

  10. 边工作边刷题:70天一遍leetcode: day 71-2

    One Edit Distance 要点:有两种解法要考虑:已知长度和未知长度(比如只给个iterator) 已知长度:最好不要用if/else在最外面分情况,而是loop在外,用err记录misma ...

随机推荐

  1. js倒计时防页面刷新

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. 最短路径—大话Dijkstra算法和Floyd算法

    Dijkstra算法 算法描述 1)算法思想:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , ...

  3. 原型 prototype

    原型 prototype js 的对象比较 由于 js 是解释执行的语言, 那么再代码中出现函数与对象如果重复执行, 会创建多个副本 在代码中重复执行的代码容易出现重复的对象 创建一个 Person ...

  4. jekyll

    bundle show minima查看安装路径 bundle exec github-pages versions 建立一个类似于master的分支,与master是完全独立 git checkou ...

  5. ruby 操作数据库语句

    1.多对多 user role u = User.first role = Role.first 插入 u.roles << role u.save 更新 u.roles = [] u.r ...

  6. 一些C语言学习的国外资源

    下面的列表是在网上收集整理的C语言资料,包括PDF等多种格式 A Tutorial on Pointers and Arrays in C Beej's Guide to C Programming ...

  7. 数位类统计问题--数位DP

    有一类与数位有关的区间统计问题.这类问题往往具有比较浓厚的数学味道,无法暴力求解,需要在数位上进行递推等操作.这类问题往往需要一些预处理,这就用到了数位DP. 本文地址:http://www.cnbl ...

  8. UIWebView的简单使用

    在iOS9.0之后需要在ifo.plist文件中添加一个配置文件,不然只能识别https开头的网址,http开头的不识别 主要有三个步骤 // 1.获取URL NSURL *url = [NSURL ...

  9. 记录Java的垃圾回收机制和几种引用

    一.Java的垃圾回收机制 Java的垃圾回收机制(java garbage collection)是Java虚拟机提供的能力,用于在空闲时间以不定时的方式动态回收无任何引用的对象占据的堆内存空间. ...

  10. Effective Java 18 Prefer interfaces to abstract classes

    Feature Interface Abstract class Defining a type that permits multiple implementations Y Y Permitted ...