版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ygrx/article/details/10431825
好久没来了,又一道庞果的题目
给定一个字符串,仅由a,b,c 3种小写字母组成。当出现连续两个不同的字母时,你可以用另外一个字母替换它,如:
- 有ab或ba连续出现,你把它们替换为字母c
- 有ac或ca连续出现时,你可以把它们替换为字母b
- 有bc或cb 连续出现时,你可以把它们替换为字母a。
你可以不断反复按照这个规则进行替换,你的目标是使得最终结果所得到的字符串尽可能短,求最终结果的最短长度。
- 输入:字符串。长度不超过200,仅由abc三种小写字母组成。
- 输出: 按照上述规则不断消除替换,所得到的字符串最短的长度。
例如:
-
输入cab,输出2。
因为我们可以把它变为bb或者变为cc
-
输入bcab,输出1。
尽管我们可以把它变为aab -> ac -> b, 也可以把它变为bbb,但因为前者长度更短,所以输出1。
一看这个题就是一个需要求最优解的问题,考虑使用动态规划算法,
- 从字符串的最开始开始搜索,发现第一个不相同的字符,记下位置
- 从这个位置开始,先把他和他后面的合并,产生一个新字符串
- 然后把他后面的和他后面的后面合并,产生第二个新字符串
- 比较这两个字符串连续一样的字符数量,取小的那个
- 接着递推这个算法,直到所有的字符都一样为止。
打个比方,题目中所说的bcab
。
- 发现第一个不相同的字符,记下位置,位置为0,因为第0个和第1个就不一样。
- 把他和他后面的合并,产生一个新字符串
bc
合并,字符串变成aab
- 把他后面的和他后面的后面合并,产生第二个新字符串 ,
ca
合并,变成bbb
aab
和bbb
比较,第一个只有两个连续相同的,第二个有三个连续相同的,舍弃第二个,取第一个- 把
aab
接着按算法进行计算。
编程的时候稍微注意一下字符串的结尾,别溢出去了。
算法比较简单,就写个主要函数吧,github上有全部的。
int _minLength(string s)
{
cout <<"String :" << s << endl;
//判断是不是所有字符都一样,如果一样,算法结束
if(countSameChars(s)==s.length())
return s.length();
//替换第一个子串
string ss1=change(s,1);
//替换第二个子串
string ss2=change(s,2);
//比较两个新串,取相同字符少的,继续该算法
if(countSameChars(ss1) <= countSameChars(ss2))
return _minLength(ss1);
else
return _minLength(ss2);
}