Leetcode:Longest Palindromic Substring

Leetcode:Longest Palindromic Substring 

问题描述

问题链接:https://oj.leetcode.com/problems/longest-palindromic-substring/


Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.

思路:

回文的问题,肯定要考虑回文的特征。

回文的基本特征就是对称性,关于字符串对称的话,肯定要考虑对称轴是一个字符或者对称轴是字符间隙,也就是回文的长度是奇数还是偶数。考虑回文的这个特性就不会有露掉的情况。

接下来考察问题,问题已知的信息:

1. 寻找的是对象是回文

2. 对对象的要求有:最长的回文,长度不超过1000,并且最长的回文是唯一的


因此现在的第一个问题就是寻找字符串中的回文。在一个字符串中回文可以通过两个索引确定前索引和后索引,由于回文具有对称性,所以也可以通过使用对称轴的位置和回文的长度的一半来表述一个回文,这里使用的是后者,因为可以通过对称轴进行遍历查找回文。


代码的思路就是,首先设置两个和字符串长度相同(其实完全可以只开辟一个数组空间,长度就是字符串的长度)保存一个标记,数组表示的是在数组下标i位置是否是最长的回文的对称轴。我代码中使用的是两个数组,一个用于保存奇数长度的回文,一个用于保存偶数长度的回文。

程序实现是通过不断增加回文的长度,一直到最大长度,通过两趟循环分别寻找奇数和偶数的最长回文的对称轴位置,程序中由于开辟了两个数组所以可以写成一趟循环。

整个算法的时间复杂度应该是O(n)(没有严格证明,如果错误望指正),空间复杂度O(n)


代码实现


/*
author: jtr@BNU
date : 14.8.10
Longest Palindromic Substring
Given a string S, find the longest palindromic substring in S. 
You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.

*/

#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <set>

using namespace std;

string longestPalindrome(string s) {
	string res;
	if (s.size() < 2)
	{
		return s;
	}
	int count = s.size();
	int maxlen = 0;
	int location = -1;
	vector<bool> odd(count, true);
	vector<bool> even(count,false);

	 for (int i = 0; i < count - 1; ++i)
	 {
	 	if(s[i] == s[i + 1]) even[i] = true;
	 }
	 bool isodd = true;
	 for (int i = 1; i < count; ++i)
	 {
	 	int temmax = 0;
	 	//odd
	 	for (int step = 0; step <= count/2; ++step)
	 	{
	 		if (odd[i])
	 		{
	 			if (i >= step && i+step < count && s[i-step] == s[i+step])
	 			{
	 				temmax = step;
	 			}
	 			else
	 			{
	 				odd[i] = false;
	 				break;
	 			}
	 		}
	 		else
	 		{
	 			break;
	 		}
	 	}
	 	if (temmax > maxlen)
	 	{
	 		maxlen = temmax;
	 		isodd = true;
	 		location = i;
	 	}

	 	//even
	 	temmax = 0;
	 	for (int step = 1; step <= count/2; ++step)
	 	{
	 		if (!even[i])
	 		{
	 			break;
	 		}
	 		else
	 		{
	 			if (i >= step && i+1+step < count && s[i-step] == s[i+1+step])
	 			{
	 				temmax = step;
	 			}
	 			else
	 			{
	 				even[i] = false;
	 				break;
	 			}
	 		}
	 	}
	 	if (temmax >= maxlen)
	 	{
	 		maxlen = temmax;
	 		isodd = false;
	 		location = i;
	 	}
	 }
	
	 if (maxlen == 0)
	 {
	 	for (int i = 0; i < count - 1; ++i)
	 	{
	 		if(s[i] == s[i + 1])
	 		{
	 			res = s.substr(i,2);
	 			return res;
	 		}
	 	}

	 }
	 if (isodd)
	 {
	 	res = s.substr(location - maxlen, 2 * maxlen + 1);
	 }
	 else
	 {
		res = s.substr(location - maxlen, 2 * (maxlen + 1));
	 }

	return res;
}

int main()
{
	string s = "bbsfadfasfcccccccccvsdfasdsaggggggggggavsdfasdccccccccdsadfscdsadafdsafdba";

	cout<<s<<endl<<longestPalindrome(s)<<endl;

	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值