Longest Happy String (M)
A string is called happy if it does not 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 happy and longest possible.s
contains at mosta
occurrences of the letter'a'
, at mostb
occurrences of the letter'b'
and at mostc
occurrences of the letter'c'
.s
will only contain'a'
,'b'
and'c'
letters.
If there is no such string s
return 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"子串的字符串被称为Happy String。要求用a个’a’、b个’b’、c个’c’组合成一个最长的Happy String。
思路
贪心。为了使得到的字符串最长,每次拼接字符时都应该尽可能消耗掉剩余数量最多的字符。步骤为:每次选出当前剩余数量最多的字符x和第二多的字符y,若x数量大于等于2,则拼接上2个x,否则拼接上1个x;此时判断x拼接后剩余数量是否比y多,若比y多则拼接上一个y,否则不需要拼接y,进入下一个循环。该步的关键思想为:每一次循环尽可能消耗掉剩余数量最多的字符,然后视情况拼接一个数量第二多的字符来当作分隔字符,以保证在下一个循环中选出的数量最多的字符x一定可以尽可能多地拼接在结果字符串的末尾(即不会出现拼接两个字符x会导致三个连续x的情况)。
解题思路及递归解法出处为LeetCode论坛解答 votrubac - C++/Java a >= b >= c。
代码实现 - 递归
class Solution {
public String longestDiverseString(int a, int b, int c) {
return helper(a, b, c, "a", "b", "c");
}
private String helper(int lg, int md, int sm, String lgc, String mdc, String smc) {
if (lg < md) return helper(md, lg, sm, mdc, lgc, smc);
if (md < sm) return helper(lg, sm, md, lgc, smc, mdc);
if (md == 0) return lgc.repeat(Math.min(lg, 2));
int lgToUse = Math.min(lg, 2);
int mdToUse = lg - lgToUse < md ? 0 : 1;
return lgc.repeat(lgToUse) + mdc.repeat(mdToUse) + helper(lg - lgToUse, md - mdToUse, sm, lgc, mdc, smc);
}
}
代码实现 - 优先队列
class Solution {
public String longestDiverseString(int a, int b, int c) {
Queue<Pair> q = new PriorityQueue<>((x, y) -> y.count - x.count);
StringBuilder sb = new StringBuilder();
if (a > 0) q.offer(new Pair('a', a));
if (b > 0) q.offer(new Pair('b', b));
if (c > 0) q.offer(new Pair('c', c));
while (q.size() > 1) {
Pair first = q.poll();
Pair second = q.poll();
sb.append(first.letter);
first.count--;
if (first.count > 0) {
sb.append(first.letter);
first.count--;
}
if (second.count <= first.count) {
sb.append(second.letter);
second.count -= 1;
}
if (first.count>0) q.offer(first);
if (second.count>0) q.offer(second);
}
if (!q.isEmpty()) {
Pair last = q.poll();
sb.append(last.letter);
last.count--;
if (last.count > 0) {
sb.append(last.letter);
}
}
return sb.toString();
}
class Pair {
char letter;
int count;
public Pair(char letter, int count) {
this.letter = letter;
this.count = count;
}
}
}