Given two integers a and b, return any string s such that:
shas lengtha + band contains exactlya'a'letters, and exactlyb'b'letters,- The substring
'aaa'does not occur ins, and - The substring
'bbb'does not occur ins.
Example 1:
Input: a = 1, b = 2
Output: "abb"
Explanation: "abb", "bab" and "bba" are all correct answers.
Example 2:
Input: a = 4, b = 1
Output: "aabaa"
Constraints:
0 <= a, b <= 100- It is guaranteed such an
sexists for the givenaandb.
题意:给定两个整数 A 和 B,返回任意字符串 S,要求满足:
S的长度为A + B,且正好包含A个'a'字母与B个'b'字母;- 子串
'aaa'没有出现在S中; - 子串
'bbb'没有出现在S中。
解法 贪心
首先想到的是贪心,哪个字母剩余的数量多,就优先使用哪个。不过这里需要分类讨论一下:
- 两个字母的数量之差小于等于
2时,比如A = 4, B = 4; A = 4, B = 5; A = 4, B = 6,这些情况下,对于剩余数量更多的字母每次使用两个,对于另一种字母也每次使用两个,如果剩下一个就全部用完; - 两个字母的数量之差大于
2时,比如A = 4, B = 7, ans = bb a bb aa bb a,此时对于剩余数量更多的字母,先每次使用两个,对于另一种字母则每次使用一个(使用两个的话,最后会剩下连续多个前一种字母,违背题意),直到两个字母的剩余数量变成第一种情况。
具体代码如下:
class Solution {
public:
string strWithout3a3b(int a, int b) {
string ans;
char x = 'a', y = 'b';
if (a < b) { swap(x, y); swap(a, b); } //使得a>=b,a:x,b:y
bool diff = a >= b + 3;
while (a || b) {
ans += string(min(a, 2), x);
a -= min(a, 2);
if (b) {
if (!diff) {
ans += string(min(b, 2), y);
b -= min(b, 2);
} else { //是否差3个及以上
ans += string(1, y);
b -= 1;
}
}
diff = a >= b + 3;
}
return ans;
}
};
运行效率如下:
执行用时:0 ms, 在所有 C++ 提交中击败了100.00% 的用户
内存消耗:5.8 MB, 在所有 C++ 提交中击败了88.47% 的用户
或者这样写:
class Solution {
public:
string strWithout3a3b(int a, int b) {
string ans;
char x = 'a', y = 'b';
if (a < b) { swap(x, y); swap(a, b); } //使得a>=b,a:x,b:y
while (a || b) {
if (a) { ans.push_back(x); --a; }
if (a && a + 1 >= b) { ans.push_back(x); --a; }
if (b) { ans.push_back(y); --b; }
//此前a==b,此时a+1==b;
//此前a==b+1,此时a==b
//此前a==b+2,此时a==b+1
//此前a>=b+3,此时a>=b+2
if (a && b && a <= b + 1) { ans.push_back(y); --b; }
}
return ans;
}
};
运行效率如下:
执行用时:0 ms, 在所有 C++ 提交中击败了100.00% 的用户
内存消耗:5.9 MB, 在所有 C++ 提交中击败了85.41% 的用户
当然,具体的填充策略不止一种,还可以:
- 两个字母的数量之差小于等于
2时,比如A = 4, B = 4; A = 4, B = 5; A = 4, B = 6,这些情况下,对于剩余数量更多的字母每次使用一个(另一种字母数量为零时全部使用),对于另一种字母也每次使用一个; - 两个字母的数量之差大于
2时,比如A = 4, B = 7, ans = bba ba ba ba bb,此时对于剩余数量更多的字母,先每次使用两个,对于另一种字母则每次使用一个(使用两个的话,最后会剩下连续多个前一种字母,违背题意),直到两个字母的剩余数量变成第一种情况。
具体代码如下:
class Solution {
public:
string strWithout3a3b(int a, int b) {
string ans;
char x = 'a', y = 'b';
if (a < b) { swap(x, y); swap(a, b); } //使得a>=b,a:x,b:y
bool diff = a >= b + 3;
while (a || b) {
if (!diff) {
if (b) {
ans += string(1, x);
--a;
ans += string(1, y);
--b;
} else {
ans += string(a, x);
a = 0;
}
} else { //是否差3个及以上
ans += string(2, x);
a -= 2;
ans += string(1, y);
--b;
}
diff = a >= b + 3;
}
return ans;
}
};
运行效率如下:
执行用时:0 ms, 在所有 C++ 提交中击败了100.00% 的用户
内存消耗:6 MB, 在所有 C++ 提交中击败了42.59% 的用户
或者这样写:
class Solution {
public:
string strWithout3a3b(int a, int b) {
string ans;
char x = 'a', y = 'b';
if (a < b) { swap(x, y); swap(a, b); } //使得a>=b,a:x,b:y
while (a || b) {
if (a) { ans.push_back(x); --a; };
if (a >= b + 2) { ans.push_back(x); --a; }
if (b) { ans.push_back(y); --b; }
}
return ans;
}
};
运行效率如下:
执行用时:0 ms, 在所有 C++ 提交中击败了100.00% 的用户
内存消耗:5.8 MB, 在所有 C++ 提交中击败了89.41% 的用户
还可以这样写:
- 两个字母的数量之差小于
2时,比如A = 4, B = 4; A = 4, B = 5,这些情况下,对于剩余数量更多的字母每次使用一个(另一种字母数量为零时全部使用),对于另一种字母也每次使用一个; - 两个字母的数量之差大于等于
2时,比如A = 4, B = 7, ans = bba ba ba ba bb,此时对于剩余数量更多的字母,先每次使用两个,对于另一种字母则每次使用一个,直到两个字母的剩余数量变成第一种情况。
对应的简化代码如下:
class Solution {
public:
string strWithout3a3b(int a, int b) {
string ans;
char x = 'a', y = 'b';
if (a < b) { swap(x, y); swap(a, b); } //使得a>=b,a:x,b:y
while (a || b) {
if (a) { ans.push_back(x); --a; };
if (a > b) { ans.push_back(x); --a; }
if (b) { ans.push_back(y); --b; }
}
return ans;
}
};
运行效率如下:
执行用时:0 ms, 在所有 C++ 提交中击败了100.00% 的用户
内存消耗:6.1 MB, 在所有 C++ 提交中击败了20.23% 的用户
本题的递归写法如下:
class Solution {
public:
string strWithout3a3b(int a, int b) {
if (a == 0) return string(b, 'b');
if (b == 0) return string(a, 'a');
if (a == b) return "ab" + strWithout3a3b(a - 1, b - 1);
return a > b ? "aab" + strWithout3a3b(a - 2, b - 1) : "bba" + strWithout3a3b(a - 1, b - 2);
}
};
运行效率如下:
执行用时:0 ms, 在所有 C++ 提交中击败了100.00% 的用户
内存消耗:6.1 MB, 在所有 C++ 提交中击败了16.94% 的用户

这篇博客介绍如何根据给定整数a和b,创建一个长度为a+b且仅包含a个'a'和b个'b'的字符串,同时确保不包含子串'aaa'和'bbb'。提供了多种贪心算法实现,包括按字母数量优势填充和分类讨论的策略。
495

被折叠的 条评论
为什么被折叠?



