暗黑的字符串-动态规划
一个只包含’A’、‘B’和’C’的字符串,如果存在某一段长度为3的连续子串中恰好’A’、‘B’和’C’各有一个,那么这个字符串就是纯净的,否则这个字符串就是暗黑的。例 如:BAACAACCBAAA 连续子串"CBA"中包含了’A’,‘B’,‘C’各一个,所以是纯净的字符串
AABBCCAABB 不存在一个长度为3的连续子串包含’A’,‘B’,‘C’,所以是暗黑的字符串
你的任务就是计算出长度为n的字符串(只包含’A’、‘B’和’C’),有多少个是暗黑的字符串。
理解:
例如n=1的时候,只有A,B,C三种情况
n = 2,有AA,AB,AC,…,CC九种情况。
n = 3的时候,n= 2的每一种情况一定能衍生出两个种情况,但是如果n=2的时候,如果后面两个字母是一样的,就可以衍生出三个。
(例如:AA可以衍生出AAA,AAB,AAC;AB可以衍生出ABA,ABB)
那么我们需要考虑的是:怎么知道n=n-1的时候最后两个字母有多少是一样的呢?
我们来回看一下:我们假设n=n-1的时候有k个最后两个字母是一样的,那么去掉最后一个字母,回退到n=n-2的情况了。
情况就清晰了,我们看一个简单的例子:
例如n=1的时候A,B,C
n=2的时候最后两个字母要一样一定要在n=1的情况上加上n=1的时候最后一个字母
所以有AA,BB,CC三种情况是最后两个字母是一样的。
所以,n=3的时候,能衍生出来的数量就是{n=2}*2+{n=1}(第一个中括号表示n=3的时候,肯定有n=2的时候每种情况衍生出两种,第二个中括号表示,n=2的时候有多少个最后两个字母是一样的)
分析:
根据上面分析,就可以写出公示了
d[i] = d[i-1]*2+d[i-2]
伪代码为
df(n)
dp [1] = 3
dp [2] = 9
for n in n-3
dp[n+3] = dp[n+2]*2+dp[n+1]
return dp[n]
算法时间复杂度为O(n)
空间复杂度为O(n)
另一种方法 空间复杂度为O(1)
我们来看,我们只需要计算第n个的时候,只需要第n-1根n-2的情况,那么我们并不需要一个数组的空间
伪代码
df(n)
if n == 1
return 3
if n == 2
return 9
else
first = 3
second = 9
for i in n-2 then
tem = first
first = second
second = second*2 + tem
return second