• 边工作边刷题:70天一遍leetcode: day 96-2


    Rearrange String k Distance Apart

    要点:这题要反向思维:如果k distance apart,那么除非最后一组,其他k组都是distinct的。greedy algorithm:显然出现次数越多,越要优先放,这样才能分布到尽可能多个streak。另外同个char最好间隔正好k。

    • 二个考虑的问题:如何按次数一个streak一个streak generate?什么情况不够条件了返回?
      • 如果每个streak都是distinct的,那么下一个放的元素要出heap,如果count不为0,再入heap来放下一个streak:这就类似level order traversal了,只不过当前层的遍历是固定的k
      • 显然heap中(当前层)元素不够了,就说明不满足条件了

    python coding

    • python要用collections.Counter()来计数,不要loop了,产生Counter object,用items()来产生一个(key,count) pair list

    https://repl.it/CaPy
    另一种解法:上面的heapq解法是每个bucket一起填充,所以不断出heap再入heap。而另一种解法是优先把某个letter填到不同的bucket里。

    • component包括:nbins,idx list(用来标注每个bin填充的位置)。

    • 公式:

      • bucket是轮流填充的,所以bucket的i公式i=(i+1)%nbins
      • nbins:(len-1)/k+1:死记,同时可以兼顾奇偶的情况
    • greedy的两点考虑:显然如果某个letter个数超过nbins,不符合。同时可能某个bin已经满了,所以新letter要放到下一个中。所以即使不同letter的个数超过k也可能。有可能其他都满了,发现最后只能和上一个重复letter放在同一个bucket里,这样也不符合。

    • https://repl.it/CaPy/1

    • 错误点

      • 公式2.1是%nbins,不是k
      • 检查是否同一个bucket要用idx[i]-1而不是idx[i-1]
      • Counter排序需要reverse
    import collections
    from heapq import *
    
    class Solution(object):
    
        def rearrangeString(self, str, k):
            """
    ........:type str: str
    ........:type k: int
    ........:rtype: str
    ........"""
    
            lettercounts = collections.Counter(str)
            countheap = []
            for c, count in lettercounts.items():
                heappush(countheap, (-count, c))
            n = len(str)
            res = []
            while countheap:
                ln = min(k, n)
                nextround = []
                for i in xrange(ln):
                    if not countheap:
                        return ""
                    count, c = heappop(countheap)
                    count+=1 # b/c count is negative 
                    if count<0:
                    	nextround.append((count, c))
                    res.append(c)
                    n -= 1
    			
                for count, c in nextround:
                    heappush(countheap, (count, c))
            return ''.join(res)
            
    s = Solution()
    # "abacabcd"
    print s.rearrangeString("aaadbbcc", 2)
    # ""
    print s.rearrangeString("aaabc", 3)
    # "abcabc"
    print s.rearrangeString("aabbcc", 3)
            
    
    # Given a non-empty string str and an integer k, rearrange the string such that the same characters are at least distance k from each other.
    
    # All input strings are given in lowercase letters. If it is not possible to rearrange the string, return an empty string "".
    
    # Example 1:
    # str = "aabbcc", k = 3
    
    # Result: "abcabc"
    
    # The same letters are at least distance 3 from each other.
    # Example 2:
    # str = "aaabc", k = 3 
    
    # Answer: ""
    
    # It is not possible to rearrange the string.
    # Example 3:
    # str = "aaadbbcc", k = 2
    
    # Answer: "abacabcd"
    
    # Another possible answer is: "abcabcda"
    
    # The same letters are at least distance 2 from each other.
    # Credits:
    # Special thanks to @elmirap for adding this problem and creating all test cases.
    
    # Hide Company Tags Google
    # Hide Tags Hash Table Heap Greedy
    
    from collections import Counter
    
    class Solution(object):
        def rearrangeString(self, str, k):
            """
            :type str: str
            :type k: int
            :rtype: str
            """
            if k==0:return str
            n = len(str)
            nbins = (n-1)/k+1
            def binsize(i, k, n):
                return min(k, n-i*k)
            
            counts = Counter(str).items()
            counts.sort(key=lambda x: x[1], reverse=True) # error 3: should be reverse order
            idx = [0]*nbins
            i = 0
            res = ['']*n
            for c, m in counts:
                if m>nbins:
                    return ""
                
                for _ in xrange(m):
                    while idx[i]>=binsize(i, k, n):
                        i = (i+1)%nbins # error 1: nbins, not k
                    offset = i*k
                    # print i, offset, idx[i]
                    if idx[i]>0 and res[offset + idx[i]-1]==c: # error 2: idx[i]-1 not idx[i-1], i is bucket number
                        return ""
                    
                    res[offset+idx[i]]=c
                    idx[i]+=1
                    i = (i+1)%nbins
            # print res
            return ''.join(res)
            
    s = Solution()
    # "abacabcd"
    assert s.rearrangeString("aaadbbcc", 2)=="acababcd"
    # ""
    assert s.rearrangeString("aaabc", 3)==""
    # "acbacb"
    assert s.rearrangeString("aabbcc", 3)=="acbacb"
    
    
  • 相关阅读:
    Spring MVC 入门示例讲解
    使用Word2013,发布博文到博客园
    走过2103,迈向2014
    C#中的字符串拼接@,$
    ORA-22922:nonexistent LOB value问题及listagg()函数
    证明一个数是不是存在于该数组中
    论java中System.arrayCopy()与Arrays.copyOf()的区别
    JSP中获取各种路径的方法
    JavaScript中变量声明有var和没var的区别
    JavaScript:理解事件循环
  • 原文地址:https://www.cnblogs.com/absolute/p/5815919.html
Copyright © 2020-2023  润新知