固定字符组成不含特定子串的定长字符串

本题为美团秋招笔试题,原题描述如下:

使用字符“a”和字符"b"组成长度为n的字符串。要求不能包含“aba”和“bab”子串。求组成的字符串的个数。

1.本题最简便解法:斐波那契数列。

        本题自己画一画,就可以发现规律是:2,4,6,10,16,26,··· 可以直接秒掉。但是本题是这个类型题目的一个特例,不属于通用解法。

2.最通用解法,树的层序遍历(BFS)

        本题通用解法为:

        1.维护一个队列,将第一层节点入队。

        2.计算队列长度length,出队的同时,分别添加字符a或字符b作为左右子节点入队,在入队之前,检查新节点的尾部是否符合要求即可。(eg:原节点aaab,添加字符a后,变为aaaba,尾部出现非法子串,不入队,进行剪枝)。

        3.循环至指定层即可。

        4.此方法时间复杂度较高,但是最好理解。

代码如下:

q = ["a","b"]//初始化
n = 10 //测试长度
count = []
for i in range(n)://循环n次
    l=len(q)
    count.append(l)

    for i in range(l):
        temp = q.pop(0)   //出队
        a = temp + "a"
        if a[-3:] != "aba": //检测入队
            q.append(a)
        b = temp + "b"
        if b[-3:] != "bab":
            q.append(b)

for i in range(n):
    print(i+1,count[i])

3.另一种通用解法

详见此博客:https://www.cnblogs.com/kcn999/p/10659838.html

我们看另一个题目:用字符a,b,c组成长度为n的字符串,但是不能包含子串“aa”

        用a[i]表示长度为i的方案数,用cnt表示a[i]中末尾为a的方案数,初始化为1。

        则可得a[i]=a[i−1]∗3−cnt,cnt=a[i−1]−cnt。

由此可进行递推求解,类比到本题,就是:

        用a[i]表示长度为i的方案数,用cnt表示a[i]中末尾为“ab”和“ba”的方案数,初始化为0。

        则可得a[i]=a[i−1]∗3−cnt,cnt=a[i−1]−cnt。

这类题目本质是:a[i]=a[i−1]∗k−cnt, k为字符个数。 但是这里的cnt其实不太好推出来。

但如果有这个思路的话,利用方法二来找规律,利用方法三来编码也可以。

后续

对于字符a,和字符b组成的定长字符串,但是不能包含子串“abaa”。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值