「这是我参与2022首次更文挑战的第22,活动详情查看:2022首次更文挑战」
1405. 最长快乐字符串
如果字符串中不含有任何 'aaa','bbb' 或 'ccc' 这样的字符串作为子串,那么该字符串就是一个「快乐字符串」。
给你三个整数 a,b ,c,请你返回 任意一个 满足下列全部条件的字符串 s:
s 是一个尽可能长的快乐字符串。
s 中 最多 有a 个字母 'a'、b 个字母 'b'、c 个字母 'c' 。
s 中只含有 'a'、'b' 、'c' 三种字母。
如果不存在这样的字符串 s ,请返回一个空字符串 ""。
示例 1:
输入:a = 1, b = 1, c = 7
输出:"ccaccbcc"
解释:"ccbccacc" 也是一种正确答案。
示例 2:
输入:a = 2, b = 2, c = 1
输出:"aabbc"
示例 3:
输入:a = 7, b = 1, c = 0
输出:"aabaa"
解释:这是该测试用例的唯一正确答案。
提示:
0 <= a, b, c <= 100
a + b + c > 0
分析
首先根据提示0 <= a, b, c <= 100
我们可以这道题对性能要求不算太高,长度最大也就300。再根据a + b + c > 0
是恒等的,说明a,b,c的数量大于等于0
且至少有一个是1
,这就是至少存在一个字符。
分析完一些基本条件,我们再来分析一下如何能使快乐字符串能够保持最长。要想保证最长我们就要充分利用这些字母,我们就要先使用数量最多的。这是因为数量最多出现连续3个一样的概率最大。
在拼接最长字符串时,我们将最多优先拼接当出现俩个一样的时我们就需要用次大的进行拼接直到出现3个一样的或使用完毕时结束拼接。
逐步实现
首先定义ans
用于存放最长快乐字符串的结果默认为""
。
let ans = "";
复制代码
首先定义arr
用于存放字母与数量的对应关系。
const arr = [{lab:"a",val:a},{lab:"b",val:b},{lab:"c",val:c}];
复制代码
为了保证我们每次使用的都是最多的那个字母,需要通过不停的进行sort
排序来保证。
while (true) {
arr.sort((a, b) => b.val - a.val);
}
复制代码
通过for of
循环来拼接字母,每次拼接完成后需要结束循环,重新排序。
for (const item of arr) {
ans = ans + item.lab;
item.val--;
break;
}
复制代码
当出现连续俩个一样但没有其他字母的情况就需要结束循环或者最大字母的数量为0时结束
while (true) {
arr.sort((a, b) => b.val - a.val);
let hasNext = false;
for (const item of arr) {
if (item.val <= 0) {
break;
}
const m = ans.length;
if (m >= 2 && ans[m - 2] === item.lab && ans[m - 1] === item.lab) {
continue;
}
hasNext = true;
ans = ans + item.lab;
item.val--;
break;
}
if (!hasNext) {
break;
}
}
复制代码
最后返回ans
即为结果
return ans;
复制代码
完整代码
/**
* @param {number} a
* @param {number} b
* @param {number} c
* @return {string}
*/
var longestDiverseString = function(a, b, c) {
let ans = "";
const arr = [{lab:"a",val:a},{lab:"b",val:b},{lab:"c",val:c}];
while (true) {
arr.sort((a, b) => b.val - a.val);
let hasNext = false;
for (const item of arr) {
if (item.val <= 0) {
break;
}
const m = ans.length;
if (m >= 2 && ans[m - 2] === item.lab && ans[m - 1] === item.lab) {
continue;
}
hasNext = true;
ans = ans + item.lab;
item.val--;
break;
}
if (!hasNext) {
break;
}
}
return ans;
};
复制代码