1. 程式人生 > 其它 >LeetCode C++ 1405. Longest Happy String【Greedy/Heap】中等

LeetCode C++ 1405. Longest Happy String【Greedy/Heap】中等

技術標籤:優先佇列-二叉堆貪心LeetCode

A string is called happy if it doesnot have any of the strings 'aaa', 'bbb'or 'ccc'as a substring.

Given three integers a, b and c, return any string s,which satisfies following conditions:

  • s is happyand longest possible.
  • s contains at most aoccurrences of the letter'a', at most
    boccurrences of the letter 'b' and at most c occurrences of the letter 'c'.
  • swill only contain 'a', 'b' and 'c'letters.

If there is no such string sreturn the empty string "".

Example 1:

Input: a = 1, b = 1, c = 7
Output: "ccaccbcc"
Explanation: "ccbccacc" would also be a correct answer.

Example 2:

Input: a = 2, b = 2, c = 1
Output: "aabbc"

Example 3:

Input: a = 7, b = 1, c = 0
Output: "aabaa"
Explanation: It's the only correct answer in this case. 

Constraints:

  • 0 <= a, b, c <= 100
  • a + b + c > 0

題意:如果字串中不含有任何 ‘aaa’‘bbb’‘ccc’ 這樣的字串作為子串,那麼該字串就是一個「快樂字串」。

給出三個整數 a

bc,返回任意一個滿足下列全部條件的字串 s

  • s 是一個儘可能長的快樂字串。
  • s最多a 個字母 'a'b個字母 'b'c 個字母 'c'
  • s 中只含有 'a''b''c' 三種字母。

如果不存在這樣的字串 s ,請返回一個空字串 ""


解法 貪心

class Solution { 
public:
    string longestDiverseString(int a, int b, int c) {
        struct cmp {
            bool operator()(const pair<int, char>& a, const pair<int, char>& b) const {
                return a.first < b.first; //數量大的字元位於堆頂
            }
        };
        priority_queue<pair<int, char>, vector<pair<int, char>>, cmp> pq;
        if (a) pq.push(make_pair(a, 'a'));
        if (b) pq.push(make_pair(b, 'b'));
        if (c) pq.push(make_pair(c, 'c')); //當字元數量不是0時進入堆中
        string ans;
        char prev = 'd', beforePrev = 'd'; //作為前兩個字元的標識
        while (!pq.empty()) {
            pair<int, char> t = pq.top(); pq.pop();
            if (t.second == prev && t.second == beforePrev) { //避免同樣的字母連續三個
                if (pq.empty()) break; //退出
                pair<int, char> a = pq.top(); pq.pop();
                pq.push(t); 
                t = a; //更換字母,和原來的t.second以及前面兩個字母一定不同
            }
            ans += t.second; //拿出數量最多的字母,新增一個到字串末端
            t.first--;       //字母數量減1
            beforePrev = prev;
            prev = t.second;
            if (t.first > 0) pq.push(t); //字元數量仍然不為0
        }
        return ans;
    } //貪心:每次都選擇剩下數量最多的字母新增
};

執行效率如下:

執行用時:4 ms, 在所有 C++ 提交中擊敗了53.72% 的使用者
記憶體消耗:6.3 MB, 在所有 C++ 提交中擊敗了70.17% 的使用者