「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战」
前言
每日一题,轻松解题
每日一题为刷题系列 每日刷一题LeetCode题,并且对题目进行分析,分享思路。
正文
:最长快乐字符串
难度:中等
题目要求:
如果字符串中不含有任何 'aaa','bbb' 或 'ccc' 这样的字符串作为子串,那么该字符串就是一个「快乐字符串」。
给你三个整数 a,b ,c,请你返回 任意一个 满足下列全部条件的字符串 s:
s 是一个尽可能长的快乐字符串。
s 中 最多 有a 个字母 'a'、b 个字母 'b'、c 个字母 'c' 。
s 中只含有 'a'、'b' 、'c' 三种字母。
如果不存在这样的字符串 s ,请返回一个空字符串 ""。
分析题目:
有的题目比较抽象,看起来可能都有些费解,那我们就用自己的语言去翻译一遍题目,让题目更容易理解,这样更好的分析题目。
一共有三个变量,每个变量都是一个整数,这个整数就对应这这个字母在字符串中能出现的最大次数,并且不能存在三个相同字母相连的情况,
举个例子
a=1,b=2,c=5,表示输出的这个字符串,!!!最多 一个a字母,两个b字母,五个c字母,可以少但不能多,并且不能出现别的字母,并且不能有三个字母相同连续。
:解题
理清思路:
要知道不同的思路,大概率会获得不同的解,因为这不是算术题,所以解不唯一,这里来分析一下这个题目该如何思考,并且做分析。
在整体思考比较困难的时候,我们可以使用贪心算法,最基础的是把一个复杂的问题,拆分成若干个简单的子问题,对当前子问题作出最优解,算法不好没关系,跟着每日一题来慢慢接触各种算法。
条件
- 由于需要输出最长的字符串,所以要尽可能多的把每个字母的数量最大化,
- 由于不能有三个相同字母连续出现,所以需要用其他字母来做其间隔 结论
- 由此可得我们使用数量最多的字母来开始,使用数量少的字母来做其间隔,这样就尽可能把数量最多的字母都用上
- 依次从当前数量最多的字母开始尝试,如果发现加入当前字母会导致出现三个连续相同字母,则跳过当前字母,直到我们找到可以添加的字母为止。实际上每次只会在数量最多和次多的字母中选择一个。
- 如果尝试所有的字母都无法添加,则直接退出,此时构成的字符串即为最长的快乐字符串。
编辑代码:
1.首先定义一个函数,设置两个变量,一个存放最终结果,一个存放传入的数据
function happyString (a,b,c) {
const res = [];
const arr = [[a, 'a'], [b, 'b'], [c, 'c']];
};
2.设置一个循环,每次取当前剩余个数最多的字母,用来排列,用第二多的进行间隔
while (true) {
arr.sort((a, b) => b[0] - a[0]);
let hasNext = false;
for (const [i, [c, ch]] of arr.entries()) {
if (c <= 0) {
break;
}
const m = res.length;
if (m >= 2 && res[m - 2] === ch && res[m - 1] === ch) {
continue;
}
hasNext = true;
res.push(ch);
arr[i][0]--;
break;
}
if (!hasNext) {
break;
}
}
- arr.sort先将数组进行排序,剩余个数最多的排最前面
- hasNext定义一个变量,用来判断是否需要继续循环
- arr.entries创建一个可迭代对象, 该对象包含了数组的键值对 扩展:
arr.entries的作用,
arr = ['a','b','c'] arr是一个普通数组加上entries后
[0, "a"]
[1, "b"]
[2, "c"]
这样arr数组没变但是现在是一个可迭代对象,该对象包含了数组的键值对
3.函数返回最终结果
function happyString(a, b, c) {
const res = [];
const arr = [
[a, 'a'],
[b, 'b'],
[c, 'c']
];
while (true) {
arr.sort((a, b) => b[0] - a[0]);
let hasNext = false;
for (const [i, [c, ch]] of arr.entries()) {
if (c <= 0) {
break;
}
const m = res.length;
if (m >= 2 && res[m - 2] === ch && res[m - 1] === ch) {
continue;
}
hasNext = true;
res.push(ch);
arr[i][0]--;
break;
}
if (!hasNext) {
break;
}
}
return res.join('');
};
- res.join将数组作为字符串返回,参数为分割字符
总结
无论做什么分析最重要,其中我们分析了题目,分析了解题思路,其实在分析完解题思路后,代码其实就是很简单的事情了,养成习惯,无论做什么之前,都要进行分析,这样有助于你更快更好的完成这件事。