「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」。
每日刷题第40天 2021.02.07
1405.最长快乐字符串
- leetcode原题链接:leetcode-cn.com/problems/lo…
- 难度:中等
- 方法:贪心
题目
- 如果字符串中不含有任何 '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 <= 100a + b + c > 0
解法
- 解题思路:贪心的思路
- 分析题目:要求找到最长的快乐字符串,且快乐字符串中不包含三个连续相同的字母。
贪心策略:
- 尽可能优先(priority)使用当前最多的字母,因为最后剩下的一定是最多的字母,且只有一种字母会剩下。
- 依次从当前最多的字母开始尝试。设:最终返回的最长快乐字符串为
ans,将a,b,c存放进数组template中。 - 每次调用
sort()函数进行排序(排好序后的数组tempt),找到当前数量最多的,每次从中拿一个。当前最多的字符为tempt[0][0]- 如果
ans长度小于2,直接拼接当前数量最多的字符即可。 ans长度大于2,比较tempt[0][0]和ans[ans.length - 1]并且tempt[0][0]和ans[ans.length - 2]是否相同,如果不相等,则将当前数量最多的字符拼接到结果字符串ans后面;- 反之,将第二多的字符中拿出一个,拼接到
ans后面。
- 如果
- 两种结束情况:
5 0 0或0 0 0,分别进行判断.
注意⚠️
- 错误思路:每次放两个字母,不一定是对的。
- 举例:比如
a:5 ,b:2- 每次拿两个出来
aabbaa - 正确答案:
aabaaba
- 每次拿两个出来
var longestDiverseString = function(a, b, c) {
// 最长的快乐字符串:每次取最长的先放,因为最长的需要在前面消耗掉,不然到后面就会缩短快乐字符串的长度
let ans = '';
if(a == 0 && b == 0 && c == 0) return ans;
let template = [['a',a],['b',b],['c',c]];
// 比较函数
let compare = function (template) {
return template.sort((a,b) => b[1] - a[1]);
}
while(true){
let tempt = compare(template);
if(tempt[0][1] == 0) return ans;
// 长度小于2的时候,直接放最长的即可
if(ans.length < 2){
ans += tempt[0][0];
template[0][1]--;
}else {
// 长度大于等于2的时候,需要判断,下一个值存储什么
let last = ans[ans.length - 1];
if(last == tempt[0][0] && last == ans[ans.length - 2]) {
// 两个条件均满足的时候,表示需要换次小于的来计算
if(tempt[1][1] == 0) return ans;
ans += tempt[1][0];
template[1][1]--;
}else {
ans += tempt[0][0];
template[0][1]--;
}
}
}
};