如果字符串中不含有任何 ‘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)