最长快乐字符串——zkp~

如果字符串中不含有任何 ‘aaa’,‘bbb’ 或 ‘ccc’ 这样的字符串作为子串,那么该字符串就是一个「快乐字符串」。
给你三个整数 a,b ,c,请你返回 任意一个 满足下列全部条件的字符串 s:
s 是一个尽可能长的快乐字符串。
s 中 最多 有a 个字母 ‘a’、b 个字母 ‘b’、c 个字母 ‘c’ 。
s 中只含有 ‘a’、‘b’ 、‘c’ 三种字母。
如果不存在这样的字符串 s ,请返回一个空字符串 “”。

现在做了几十到贪心算法之后,发现贪心策略并不难找,而是用什么样数据结构,以及怎样用数据实现贪心逻辑,所以以后贪心算法我分为三部分讲解

  • 贪心策略:讲解本题解题思路
  • 数据结构:介绍本题会用到几组数据,分别什么类型,普遍作用。
  • 代码:几组数据如何,相互协作,完成逻辑

贪心策略:

  • 前提:以aabaacaa为例,字符‘a’最多出现为min(a,(b+c+1)*2),对于‘b’,'c’也一样。
  • 策略:我们总是希望本次的选择,使以后排列更多。观察sum=min(a,(b+c+1)*2)+min(b,(a+c+1)*2)+min(c,(b+c+1)*2),发现影响最大值的不是哪个字符最多,而在于哪个字符最少。所以我们每次应该选择最多的字符排列,这样就能保证剩下的可以排更多
  • 实现:任何时刻都选择当前存量最多的字符
    例外:当前两个字符相同时,将该字符排除在候选之外

数据结构

  • 一个集合:保存更新可选字符
  • 一个字典: 可选字符:每个字符剩余量(键/值)
  • 一个列表:保存已选字符,判断后两位是否相同

代码:

class Solution:
    def longestDiverseString(self, a: int, b: int, c: int) -> str:
		#初始最大存量,并根据插入修改
        d={'a':min(a,(b+c+1)*2),'b':min(b,(a+c+1)*2),'c':min(c,(a+b+1)*2)}
        #最大可排量
        res=sum(d.values())
        #相当于列表,保存已选字符
        v=deque()
        for i in range(res):
        #更新可选集合
            s=set(['a','b','c'])
         #移除不可选字符
            if len(v)>1 and v[-1]==v[-2]:
                s.remove(v[-1])
          #选择可选剩余最大字符
            m=max(s,key=lambda x:d[x])
            #移除
            v.append(m)
            #修改剩余量
            d[m]-=1
     		#连接字符
        return ''.join(v)

你可能感兴趣的:(贪心算法)