#5 最长回文子串

我写的代码:

怎么说吧,自己写的一点算法都没有,完全是暴力穷举,而且没有丝毫的美学存在的,还格外的费事!
这么求解时间消耗的太高,很容易就出现超过规定的时间。这种代码很明显的反应了我关于解决问题的方法(?暴力穷举法)这些东西还是太陌生,没有解决问题的概念。

class Solution {
public:
 string longestPalindrome(string s) {
  	int j = 1, size, i, type = 0, flag = 0, k, temp = 0;
  	string::iterator it2;
  	size = s.size();
  	for (auto it = 1 + s.begin(); it != s.end(); it++) {
   		if (*(it - i) == *(it + i)) {
    		for (i = 1; i < (size + 1) / 2; i++) {
     			if (*(it - i) != *(it + i)) {
      				j = 0;
     				break;
     			}
     			type = 1;
     			++temp;
    			if (flag < temp) {
      				flag = temp;
      				it2 = it;}
   		}   	}
   		else if(*it == *(it + 1)) {
    			for (i = 1; i < (size + 1) / 2; i++){
     			if (*(it - i) != *(it + i + 1)) {
      				j = 0; 
      				break;
     			}
     			type = 2;
     			++temp;
     			if (flag < temp) {
      				flag = temp;
      				it2 = it;
     			}
     			if (!j)break;
   	 } } }
  if (type == 1)
  	return string(it2 - flag + 0, it2 + flag + 1);
  else if (type == 2)
   	return string(it2 - flag + 1, it2 + flag + 2);
  else
   	return string("wrong");
 }
};

别人写的代码:

1.动态规划法:

//伪代码:
P(i,j); //i<j
if(P(i,j)==true)
	子串S(i)...S(j)是回文子串;
else 
	其他情况
p(i,i)==true;
P(i,i+1)=( (S(i)==S(i+1) )

嗯呃,从这里可以看出我的思路确实是动态规划的角度上出发的,但是问题就是我如何把一个动态规划的问题写的稀烂呢?
这就是一个比较严重的问题了,在学习过程中好好反省下。

class Solution {
public:
 string longestPalindrome(string s) {
  	int len = s.size();
  	if (len == 0 || len == 1)
   		return s;
  	int start = 0;//回文串起始位置
  	int max = 1;//回文串最大长度
  	vector<vector<int>>  dp(len, vector<int>(len));//定义二维动态数组
  	for (int i = 0; i < len; i++)//初始化状态
  	{
   		dp[i][i] = 1;
   		if (i < len - 1 && s[i] == s[i + 1]){
    			dp[i][i + 1] = 1;
   			max = 2;
    			start = i;}  }
    	//l表示检索的子串长度,等于3表示先检索长度为3的子串
  	for (int l = 3; l <= len; l++){
   		for (int i = 0; i + l - 1 < len; i++){
   			 int j = l + i - 1;//终止字符位置
    			 if (s[i] == s[j] && dp[i + 1][j - 1] == 1){
     				dp[i][j] = 1;
     				start = i;
     				max = l;}}  }
  	return s.substr(start, max);//获取最长回文子
  	}
};

问题主要出在哪里呢?
第一个就是如何设置条件检查相邻的字符相等,可以搞一个二维数组来保存两个数的顺序并且以值的兴事来给出相等关系
然后设置完条件之后就是比较和查找的方法,我们根据第一部设置的值然后进行循环,在条件为真的情况下继续比较下一轮并且时刻设置参数。

2.中心扩展法:

中心扩展法核心的思路:

  1. 确定一个中心
  2. 以这个中心为起点开始开始查找周围多少个字符相等
  3. 遍历整个字符串最后返回最长的字符串
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
class Solution {
public:
 	string longestPalindrome(string s) {
  	int size = s.size();
  	int maxlth=0, start=0,end=0,begin;
  	for (int i = 0; i < size-1; i++)
  	{
  		int ssin = Select(s, i, i);
   		int sdou = Select(s, i, i + 1);
   		int temp=max(ssin,sdou);            
   		if(temp>maxlth){                
   			maxlth=temp;                
   			start=i-(maxlth-1)/2;            
   		}
  	}
  	return s.substr(begin, maxlth);
 }
private:
 	int Select(string s, int left, int right) {
 	int size = s.size();
  	while (left >= 0 && right < size&&s[left]==s[right]) {
   		left--;
   		right++;
  	}
  	return right - left - 1;
 }
};
class Solution {
public:
	 string manacher(string ori_s) {
  	string s = "#";
  	for (auto c : ori_s) {
  	s += c;
   	s += "#";
  }
  	int N = s.size();
  	vector<int> radius(N, 0);
  	int C = 0;
  	int R = 0;
  	int max_c = 0;
  	int max_r = 0;
  	for (int i = 0; i < N; ++i) {
   		if (i <= R) radius[i] = min(R - i, radius[2 * C - i]);
   		while (radius[i] + 1 + i < N && i - radius[i] - 1 >= 0 &&
    		s[radius[i] + 1 + i] == s[i - radius[i] - 1]) ++radius[i];
   		if (radius[i] + i > R) {
    			R = radius[i] + i;
    			C = i;
   		}
   		if (radius[i] > max_r) {
    			max_r = radius[i];
    			max_c = i;
   		}
  }
  	string res;
  	for (int i = max_c - max_r; i <= max_c + max_r; ++i) {
   			if (s[i] != '#') res += s[i];
  }
  		return res;
 }
 	string longestPalindrome(string s) {	return manacher(s); }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值