不含 AAA 或 BBB 的字符串

100 阅读1分钟

这是我参与「掘金日新计划 · 2 月更文挑战」的第 19 天,点击查看活动详情

问题描述

给定两个整数 a 和 b ,返回 任意 字符串 s ,要求满足:

s 的长度为 a + b,且正好包含 a 个 'a' 字母与 b 个 'b' 字母; 子串 'aaa' 没有出现在 s 中; 子串 'bbb' 没有出现在 s 中。

示例 1:

输入:a = 1, b = 2
输出:"abb"
解释:"abb", "bab""bba" 都是正确答案。

示例 2:

输入:a = 4, b = 1
输出:"aabaa"

提示:

  • 0 <= a, b <= 100
  • 对于给定的 a 和 b,保证存在满足要求的 s

思路分析

首先我们先要理解一下题目意思,题目会给我们两个整数 a 和 b,分别代表我们又有字符ab的数量,我们需要使用所有的ab字符去构造一个字符串,字符串需要满足一个要求:子串 aaabbb 没有出现在 s 中。

简单了解了题目之后,我们知道了题目的要求其实就是要我们使用指定数量的ab字符构造一个字符串,且字符串中不能有连续 3 个相同的字符,因为题目保证对于给定的 a 和 b,存在满足要求的 s ,我们可以这样做:

  • 1、判断a,b两值的大小

我们应该先判断a,b两值的大小,字符串应该要以值较大的字符开头。

let max = Math.max(a, b);
let min = Math.min(a, b);
  • 2、拼接字符串

交替拼接字符串,满足条件的拼接方法有两种: aabbaab,我们只需要判断后面拼接的字符数量应该是多少,这个数量我们可以通过ab的大小关系来判断,如果ab的大小相同,那么我们可以ab都拼接两个,得到aabb,如果a > b,那么我们只能拼成字符串aab,因为b字符的数量较少,如果还取两个的话,后面字符串会不够,导致出现aaa的情况。

let res = "";
while (max > 0) {
  res += "m".repeat(Math.min(max, 2));
  max -= 2;
  if (min <= 0) break;
  if (min < max) {
    res += "n";
    min--;
  } else {
    res += "n".repeat(Math.min(min, 2));
    min -= 2;
  }
}
  • 3、使用ab替换字符

因为前面我们只判断ab的大小关系,并使用不同字符代替ab字符来构成一个字符串,所以最后我们还要根据ab之间的大小关系来将字符串中的字符替换回来。

res = res.replace(/m/g, a > b ? "a" : "b");
res = res.replace(/n/g, a > b ? "b" : "a");

完整 AC 代码如下:

AC 代码

/**
 * @param {number} a
 * @param {number} b
 * @return {string}
 */
var strWithout3a3b = function (a, b) {
  let max = Math.max(a, b);
  let min = Math.min(a, b);
  let res = "";
  while (max > 0) {
    res += "m".repeat(Math.min(max, 2));
    max -= 2;
    if (min <= 0) break;
    if (min < max) {
      res += "n";
      min--;
    } else {
      res += "n".repeat(Math.min(min, 2));
      min -= 2;
    }
  }
  res = res.replace(/m/g, a > b ? "a" : "b");
  res = res.replace(/n/g, a > b ? "b" : "a");
  return res;
};

说在后面

本人为算法业余爱好者,平时只是随着兴趣偶尔刷刷题,如果上面分享有错误的地方,欢迎指出,感激不尽。