贪心题目:不含 AAA 或 BBB 的字符串

文章目录

题目

标题和出处

标题:不含 AAA 或 BBB 的字符串

出处:984. 不含 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 的情况做法相同,只要将两个字母交换即可。

  1. 当 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。

  2. 如果 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。

  3. 如果 a > 0 a > 0 a>0 且 b = 0 b = 0 b=0,则将剩余的 'a' \text{`a'} 'a' 拼接到 s s s 的末尾。

上述做法使用贪心策略,贪心策略的正确性说明如下。

  1. 当 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',因此不会出现三个相同的连续字母。

  2. 由于保证存在满足要求的 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)。

相关推荐
伟大的车尔尼1 天前
贪心题目:最少的后缀翻转次数
贪心
lvwangshu2 天前
P12960 毒药 题解
动态规划·题解·贪心·技巧·性质题·思维好题
伟大的车尔尼11 天前
贪心题目:优势洗牌
贪心
Logic10111 天前
C语言/数据结构动态规划题解:Kadane算法求最大子数组和——O(n)时间O(1)空间
c语言·数据结构·动态规划·贪心·时间复杂度·算法题·最大子数组和
伟大的车尔尼13 天前
贪心题目:分发饼干
贪心
Tisfy14 天前
LeetCode 2472.不重叠回文子字符串的最大数目:动态规划(贪心)
动态规划·字符串·题解·贪心·dp·回文字符串
伟大的车尔尼18 天前
贪心题目:三角形的最大周长
贪心
青少儿编程课堂19 天前
贪心算法进阶:区间调度与最少资源整合解析
c++·python·算法·贪心·信息学竞赛·区间调度
伟大的车尔尼22 天前
贪心题目:保持城市天际线
贪心