文章目录
题目
标题和出处
标题:不含 AAA 或 BBB 的字符串
难度
4 级
题目描述
要求
给定两个整数 a \texttt{a} a 和 b \texttt{b} b,返回任意 满足以下要求的字符串 s \texttt{s} s:
- s \texttt{s} s 的长度为 a + b \texttt{a} + \texttt{b} a+b,且正好包含 a \texttt{a} a 个字母 'a' \texttt{`a'} 'a' 与 b \texttt{b} b 个字母 'b' \texttt{`b'} 'b'。
- 子串 "aaa" \texttt{"aaa"} "aaa" 没有出现在 s \texttt{s} s 中。
- 子串 "bbb" \texttt{"bbb"} "bbb" 没有出现在 s \texttt{s} s 中。
示例
示例 1:
输入: a = 1, b = 2 \texttt{a = 1, b = 2} a = 1, b = 2
输出: "abb" \texttt{"abb"} "abb"
解释: "abb" \texttt{"abb"} "abb"、 "bab" \texttt{"bab"} "bab" 和 "bba" \texttt{"bba"} "bba" 都是正确答案。
示例 2:
输入: a = 4, b = 1 \texttt{a = 4, b = 1} a = 4, b = 1
输出: "aabaa" \texttt{"aabaa"} "aabaa"
数据范围
- 0 ≤ a, b ≤ 100 \texttt{0} \le \texttt{a, b} \le \texttt{100} 0≤a, b≤100
- 对于给定的 a \texttt{a} a 和 b \texttt{b} b,保证存在满足要求的 s \texttt{s} s
解法
思路和算法
这道题要求构造字符串 s s s,满足由 a a a 个字母 'a' \text{`a'} 'a' 和 b b b 个字母 'b' \text{`b'} 'b' 组成,且不存在三个相同的连续字母,因此相同字母最多连续出现两次。
在 b b b 的值确定的情况下, a a a 的值最大时对应的 s s s 由 b b b 组 "aab" \text{``aab"} "aab" 以及一组 "aa" \text{``aa"} "aa" 构成,此时 s s s 的长度是 a + b = 3 b + 2 a + b = 3b + 2 a+b=3b+2,因此 a = 2 b + 2 a = 2b + 2 a=2b+2。当 b = 0 b = 0 b=0 时也适用。
同理可知,在 a a a 的值确定的情况下, b b b 的最大值是 2 a + 2 2a + 2 2a+2。
因此非负整数 a a a 和 b b b 满足 0 ≤ a ≤ 2 b + 2 0 \le a \le 2b + 2 0≤a≤2b+2 和 0 ≤ b ≤ 2 a + 2 0 \le b \le 2a + 2 0≤b≤2a+2。
当 a = b a = b a=b 时,用 x x x 表示每个字母的出现次数,则 s s s 可以由 x x x 组 "ab" \text{``ab"} "ab" 构成,此时 s s s 中的任意两个相邻字母都不相同。
当 a ≠ b a \ne b a=b 时,出现次数较多的字母将在 s s s 中连续出现,构造时应满足相同字母最多连续出现两次。以下考虑 a > b a > b a>b 的情况,对于 a < b a < b a<b 的情况做法相同,只要将两个字母交换即可。
-
当 a > b > 0 a > b > 0 a>b>0 时,每次将一组 "aab" \text{``aab"} "aab" 拼接到 s s s 的末尾,则每次使用两个 'a' \text{`a'} 'a' 和一个 'b' \text{`b'} 'b',因此将 a a a 的值减 2 2 2,将 b b b 的值减 1 1 1,此时 s s s 中不存在三个相同的连续字母。重复该操作,直到 a = b a = b a=b 或 b = 0 b = 0 b=0。
-
如果 a = b a = b a=b,则每次将一组 "ab" \text{``ab"} "ab" 拼接到 s s s 的末尾,每次使用一个 'a' \text{`a'} 'a' 和一个 'b' \text{`b'} 'b',因此将 a a a 的值减 1 1 1,将 b b b 的值减 1 1 1,此时 s s s 中不存在三个相同的连续字母。重复该操作,直到 a = b = 0 a = b = 0 a=b=0。
-
如果 a > 0 a > 0 a>0 且 b = 0 b = 0 b=0,则将剩余的 'a' \text{`a'} 'a' 拼接到 s s s 的末尾。
上述做法使用贪心策略,贪心策略的正确性说明如下。
-
当 a > b > 0 a > b > 0 a>b>0 时,每次将一组 "aab" \text{``aab"} "aab" 拼接到 s s s 的末尾,因此 s s s 为空或者 s s s 的最后一个字母是 'b' \text{`b'} 'b'。由于每一次拼接的两个或三个字母都以 'a' \text{`a'} 'a' 开始且最多有两个连续的 'a' \text{`a'} 'a',因此不会出现三个相同的连续字母。
-
由于保证存在满足要求的 s s s,因此当 a > 0 a > 0 a>0 且 b = 0 b = 0 b=0 时,必有 a ≤ 2 a \le 2 a≤2,此时 s s s 为空或者 s s s 的最后一个字母是 'b' \text{`b'} 'b',将剩余的 'a' \text{`a'} 'a' 拼接到 s s s 的末尾不会出现三个相同的连续字母。
代码
java
class Solution {
public String strWithout3a3b(int a, int b) {
StringBuffer sb = new StringBuffer();
while (a > b && b > 0) {
sb.append("aab");
a -= 2;
b--;
}
while (b > a && a > 0) {
sb.append("bba");
b -= 2;
a--;
}
while (a > 0 && b > 0) {
sb.append("ab");
a--;
b--;
}
while (a > 0) {
sb.append("a");
a--;
}
while (b > 0) {
sb.append("b");
b--;
}
return sb.toString();
}
}
复杂度分析
-
时间复杂度: O ( a + b ) O(a + b) O(a+b),其中 a a a 和 b b b 分别是 s s s 中的字母 'a' \text{`a'} 'a' 和字母 'b' \text{`b'} 'b' 的个数。需要构造长度为 a + b a + b a+b 的字符串,拼接每个字母的时间是 O ( 1 ) O(1) O(1)。
-
空间复杂度: O ( a + b ) O(a + b) O(a+b),其中 a a a 和 b b b 分别是 s s s 中的字母 'a' \text{`a'} 'a' 和字母 'b' \text{`b'} 'b' 的个数。需要创建一个长度为 a + b a + b a+b 的 StringBuffer \texttt{StringBuffer} StringBuffer 或 StringBuilder \texttt{StringBuilder} StringBuilder 类型的对象。由于 Java 中的 String \texttt{String} String 类型的对象不可变,因此空间复杂度至少为 O ( a + b ) O(a + b) O(a+b)。