C++每日一练:小艺照镜子(详解分治法)
文章目录
- 前言
- 一、题目
- 二、解题
- 1.分析
- 总结
前言
大过节的,不想去看人后脑勺,就做点题来玩。挑了小艺照镜子,百分通过~
提示:以下是本篇文章正文内容,下面案例可供参考
一、题目
题目名称:
小艺照镜子
题目描述:
已知字符串str。 输出字符串str中最长回文串的长度。
输入描述:
输入字符串s.(1<=len(str)<=10000)
示例:
输入
abab
输出
3
二、解题
1.分析
这题 初一看挺简单的,先取最大值 0 到 字符长度,然后不停的减小长度比较就行了,结果行不通。纠结好半天,改变思路,先假设最小的情况2或3个,再不停增大,一直到前后不相同。
分三个函数来解释:
函数一:用来测试aba的情况下的回文串
int test_odd(string &s, int m){
int l = m-1, r = m+1, len = 1;
while(l >=0 && r < (int)s.length()){
if(s[l] == s[r]) l--, r++, len += 2;
else break;
}
return len;
}
很简单的代码,m为中间的b,则l就是a,r也是a。初始就是1个回文,找到l和r相同,就加2个。如此从m为1到结束。就找出了所有奇数情况的回文串,并取得最大的一个。
函数二:用来测试baab的情况下的回文串
int test_even(string &s, int m){
int l = m, r = m+1, len = 0;
while(l>=0 && r<(int)s.length()){
if(s[l] == s[r]) l--, r++, len += 2;
else break;
}
return len;
}
这和上在的逻辑差不多,不过就是从s[0] 与s[1] 比较开始罢了,不用解释了吧~
函数三:综合循环一下就好了,就是solution部分。
完整代码:
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
int test_odd(string &s, int m){
int l = m-1, r = m+1, len = 1;
while(l >=0 && r < (int)s.length()){
if(s[l] == s[r]) l--, r++, len += 2;
else break;
}
return len;
}
int test_even(string &s, int m){
int l = m, r = m+1, len = 0;
while(l>=0 && r<(int)s.length()){
if(s[l] == s[r]) l--, r++, len += 2;
else break;
}
return len;
}
int solution(std::string s){
int result = 1;
// TODO:
int L = s.length(), res_odd = 0, res_even = 0;
if (L>=2){
for (int i=1; i<L; ++i){
if(s[i-1] == s[i+1]){
res_odd = max(res_odd, test_odd(s, i));
};
}
for(int i=0; i<L; ++i){
if (s[i] == s[i+1]){
res_even = max(res_even, test_even(s, i));
}
}
}
result = max(result, max(res_odd, res_even));
return result;
}
int main() {
std::string s="abc";
//getline(std::cin, s);;
int result = solution(s);
std::cout<<result<<std::endl;
return 0;
}
看solution部分:因为至少一个字母的情况也能算是回文,所以就默认值为1。
先找出奇数情况下最长的回文,再找出偶数情况下的。
为了尽量减少循环,笔者在调用奇、偶查找之前,先设了一个条件:
奇数情况要求:if(s[i-1] == s[i+1])
偶数情况要求:if (s[i] == s[i+1])
也就是最少要存在回文大于1的情况才去查找是不是有更多的回文。
这样能极大的减少两个查找函数的调用,要不然怕是可能会超时。
最后result = max(result, max(res_odd, res_even));
找出最大值就完事!
总结
把一个较复杂的问题,分解成若干个较简单的问题,这应该也算是分治法了吧~ 分而治之嘛!