不含 AAA 或 BBB 的字符串--先奏后斩思想

0x01.问题

给定两个整数 AB,返回任意字符串 S,要求满足:
1.S 的长度为 A + B,且正好包含 A'a' 字母与 B'b' 字母;
2.子串 'aaa' 没有出现在 S 中;
3.子串 'bbb' 没有出现在 S 中。
提示:0 <= A <= 100 0 <= B <= 100
对于给定的 AB,保证存在满足要求的 S

C++函数形式为:string strWithout3a3b(int A, int B)

0x02.分析

题目保证一定存在这样的S,我们可以逆向的分析一下,当两个整数需要满足什么样的情况时,才一定能保证存在这样的S呢?

来一个极端的思想,如果A非常多,B非常少,AB之间存不存在制约呢?

我们很容易得出这样的极端情况就是A=2B+2,也就是每两个a后都跟着一个b,最后还有两个a的情况。如果a再多一个,就找不到合适的位置了。相反,如果ba少,也是一样的情况。

于是我们就有思路了,假如ab少,我们可以先按照b的数量构造出一个极端情况的字符串,然后,再根据a的数量从两个相邻的里面删去一个。反过来也是一样的做法。

还有就是A==B的情况,这时候,只要一个接一个的加上去就行了。

整个题的思路:

  • 先构造极端条件,再根据实际数量删去相应的重复字符。
  • 先奏后斩,哈哈。

0x03.解决代码

class Solution {
public:
    string strWithout3a3b(int A, int B) {
        string s;
        if(A==B){
            s="";
            for(int i=0;i<A+B;i++){
                if(i%2==0) s+='a';
                else s+='b';
            }
            return s;
        }
        if(A>B){
            s="";
            int a=0,b=0;
            for(int i=0;i<3*B+2;i++){
                if(a<2){
                    s+='a';
                    a++;
                }
                else{
                    s+='b';
                    b++;
                    a=0;
                    if(b>=B){
                        s+="aa";
                        break;
                    }
                }
            }
            int num=2*B+2-A;
            for(int i=0;i<num;i++){
                s.erase(i*2,1);
            }
            return s;
        }
        else{
            s="";
            int b=0,a=0;
            for(int i=0;i<3*A+2;i++){
                if(b<2){
                    s+='b';
                    b++;
                }
                else{
                    s+='a';
                    a++;
                    b=0;
                    if(a>=A){
                        s+="bb";
                        break;
                    }
                }
            }
            int num=2*A+2-B;
            for(int i=0;i<num;i++){
                s.erase(i*2,1);
            }
            return s;
        }
        return s;
    }
};

ATFWUS  --Writing  By 2020–03–20

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ATFWUS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值