——————————————————————————————— M 1 ————————————————————————————————
解题思路:
穷举str的所有子串,调用回文串判断函数bool isPalindromeStr(string s)
注意事项:
设n为字符串长度,判断一个回文串 O(n),遍历所有字串 O(n2),总时间复杂度 O(n3) ,空间复杂度 O(n) 用来存字符串
参考代码:
#include<bits/stdc++.h>
using namespace std;
bool isPalindromeStr(string s)
{
int len = s.length();
int len_half = len / 2;
for (int i = 0; i < len_half; ++i) {
if (s[i] != s[len - 1 - i]) return false;
}
return true;
}
int main()
{
string s;
while (cin >> s) {
int i, j;
int sLen = s.length();
int maxLen = 0;
// 核心:两层循环,依次检索 substr(i, j) 即 s[i] 开始,长度为 j 的子串
for (i = 0; i < sLen; ++i) {
for (j = sLen - i; j >= 1; --j) {
if (isPalindromeStr(s.substr(i, j)) && j > maxLen) {
maxLen = j;
}
}
}
cout << maxLen << endl;
}
return 0;
}
——————————————————————————————— M 2 ————————————————————————————————
解题思路:
以字符或空隙作为中心,扩展子串,判断str的部分子串
优化原理:若 abc 不为回文串,则 xabcx 也不会是回文串,再向外延伸也不满足,以此减少判断的子串数量
优化后,设n为字符串长度,判断一个回文串 O(n),遍历所有字串 O(n),总时间复杂度 O(n2) ,空间复杂度 O(n) 用来存字符串
(这一步遍历所有字串 O(n)说实话我还没完全理解,但是应该接近这个数量级
注意事项:
代码比较繁杂,重复度高,有兴趣的可以看看.....不打算优化结构了,还要学马拉车算法......
举个例子:str = "abc"
以字符为中心扩展:a / b, abc / c
以空隙为中心扩展:ab / bc
难以理解的话,用#代替空隙:str = "a#b#c" 【实际上,这样填充得到的字符串,与原字符串的回文特性等价】
代码中多处break避免了无意义的判断,使得寻找最长回文字串变成了一个有大致方向的寻找。希望这样的表述还算可以......
如:str = "adaelele" 穷举有36个字串 优化后:以标红的e为中心扩展:e ——> lel ——> elele
参考代码:
#include<bits/stdc++.h>
using namespace std;
bool isPalindromeStr(string s)
{
int len = s.length();
int len_half = len / 2;
for (int i = 0; i < len_half; ++i) {
if (s[i] != s[len - 1 - i]) return false;
}
return true;
}
int main()
{
string s;
while (cin >> s) {
int i, j, k;
int sLen = s.length();
int maxSLen = 0;
string maxS;
// 前半部分 s[0]~s[len/2 - 1]
for (i = 0; i < sLen / 2; ++i) {
// 判断字符
for (j = 1, k = i; k >= 0; j += 2, --k) {
if (isPalindromeStr(s.substr(k, j))) {
if (j > maxSLen) {
maxS = s.substr(k, j);
maxSLen = j;
}
}
else break;
}
// 判断空隙
for (j = 2, k = i; k >= 0; j += 2, --k) {
if (isPalindromeStr(s.substr(k, j))) {
if (j > maxSLen) {
maxS = s.substr(k, j);
maxSLen = j;
}
}
else break;
}
}
// 后半部分 s[len/2]~s[len-1]
for (i = sLen / 2; i < sLen; ++i) {
// 判断字符
for (j = 1, k = i; j + k <= sLen; j += 2, --k) {
if (isPalindromeStr(s.substr(k, j))) {
if (j > maxSLen) {
maxS = s.substr(k, j);
maxSLen = j;
}
}
else break;
}
// 判断空隙
for (j = 2, k = i; j + k <= sLen; j += 2, --k) {
if (isPalindromeStr(s.substr(k, j))) {
if (j > maxSLen) {
maxS = s.substr(k, j);
maxSLen = j;
}
}
else break;
}
}
cout << maxSLen << endl;
}
return 0;
}
——————————————————————————————— M 3 ————————————————————————————————
马拉车算法迟点补......
0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复