三字母字符串组合
来源:互联网 发布:视频拼接软件 编辑:程序博客网 时间:2024/04/30 12:26
本总结是是个人为防止遗忘而作,不得转载和商用。
题目
仅由三个字符A、B、C构成字符串,且字符串任意三个相邻元素不能完全相同。如“ACCCAB”不合法,“ABBCBCA”合法。
求满足条件的长度为n的字符串个数。
PS1:假定不考虑整数溢出
PS2:要求时间和空间复杂度不高于O(N)。
分析
若当前已经有了所有长度为n-1的合法字符串,如何在末端增加一个字符,形成长度为n的字符串呢?
为了解决此问题就需要将长度为n-1字符串分成“末尾两个字符不相等”和“末尾两个字符相等”两种情况,各自数目记做dp[n-1][0], dp[n-1][1],即:
dp[n][0]:长度为n的字符串最后两个不相同
dp[n][1]:长度为n的字符串最后两个相同
然后分别考虑这两种情况。
1,要想使“长度为n的字符串最后两个不相同”,则“长度为n-1的字符串的最后两个字符可以相等,可以不相等,且相等有两种情况,不相等有两种情况”,如:
下面的红色字母是第n位
n-1的字符串的最后两个字符相等时,长度为n的字符串最后两个不相同:
情况1:ABCAABABBC
情况2:ABCAABABBA
n-1的字符串的最后两个字符不相等时,长度为n的字符串最后两个不相同:
情况1:ABCAABABAC
情况2:ABCAABABAB
所以dp[n][0] = 2*dp[n-1][0] + 2*dp[n-1][1]。
2,要想使“长度为n的字符串最后两个相同”,则“长度为n-1的字符串的最后两个字符只能不相等,且只有一种情况”,如:
下面的红色字母是第n位
情况1:ABCAABABAA
所以dp[n][1] = dp[n-1][0]
最后,初始条件是:
dp[1][0]= 3
dp[1][1]= 0
状态转移方程
现在就可以写出状态转移方程了,如下:
初始条件:
dp[1][0] = 3
dp[1][1]= 0
状态转移方程:
dp[n][0] = 2*dp[n-1][0] +2*dp[n-1][1]
dp[n][1]= dp[n-1][0]
滚动数组
按理说有了初始条件和状态转移方程就可以写代码了,不过可以在优化优化。
因为有了长度n-1的字符串的数量就可以计算长度为n的,有了长度为n的就可以计算长度为n+1的,所以没必要将n-1的所有情况都保存,只需要记录当前的就OK了。
所以状态转移方程可以更新成“滚动数组”的样子,如下。
dp[0]= 2*dp[0] + 2*dp[1]
dp[1]= dp[0]
PS:使用滚动数组,将空间复杂度由O(N)降到O(1)
代码
于是代码就好简单好简单,如下:
int CalcCount(int n){ // 初始条件 int nNonRepeat = 3 int nRepeat = 0; // 滚动数组 int t; for (int i = 2; i <= n; i++) { t = nNonRepeat; nNonRepeat = 2*(nNonRepeat + nRepeat); nRepeat = t; } return nRepeat + nNonRepeat;}
不过还可以再优化!
你看,对于滚动数组,如果把dp[0]看成x,dp[1]看成y的话,那这个式子就可以写出下面的样子:
x= 2x + 2y
y= x
如果用矩阵表达的话就是:
即:我们就是在求(x,y)这么一个向量在矩阵的作用下不停的迭代的过程,即:
而这里最后需要计算一个n-1次幂,这就可以使用http://blog.csdn.net/xueyingxue001/article/details/52913274中介绍的方法,这样一来就可以将时间复杂度降为了O(logN)
- 三字母字符串组合
- 算法学习-三字母字符串组合
- 转换abc三种字母组合的字符串
- 对字符串中的字母进行组合
- 正则表达式校验字母和字符串组合
- C# 字符串字母的大小写组合
- 给定一串字符串,将字母组合在一起。
- 求a-z26个字母的三三组合
- 字符串之输出所有字母组合相同的单词
- 字符串的排列组合(组合需无重复字母)
- C++ 随机生成数字和字母组合的字符串
- JS生成随机的由字母数字组合的字符串
- 数组字符串转换为字母组合的种数
- 数字字符串转换为字母组合的种数算法
- C#生成8位字母数字组合随机的字符串
- 数字字符串转换为字母组合的种数
- 数字字符串转换为字母组合的种数
- web前端js中随机生成指定位数的字母数字、组合字符串可选择字母大小写
- Linux命令之"top"
- 进度条(贝塞尔曲线)
- xgboost: 速度快效果好的boosting模型
- KMP算法
- 网络编程(21)—— 使用epoll进行IO复用
- 三字母字符串组合
- intellij idea 白色光标问题
- MongoDB 写安全(Write Concern)
- 算法-第四版-练习1.3.20解答
- 正则表达式的学习笔记
- Unity客户端框架
- 网站根目录下常用文件及代码
- RecyclerView只能显示一行的问题
- Joda-Time 简介和使用