leetcode--5 Longest Palindromic Substring
1. 题目:
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.
注:
palindromic substring :回文序列,如:aba,abba 等。
2.1 C++ 暴力解决—— 时间复杂度O(N³)
思路:
(1). 构造一个map,存储原字符出现的所有位置;
(2). 从头到位扫描字符串,根据map中的位置,选取子字符串,判断是否为回文序列
class Solution {
public:
string longestPalindrome(string s) {
unsigned long long string_len=s.length();
if(string_len==0)
return "";
if(string_len==1)
return s;
string current_str="",longest_str="";
unsigned long long current_len=0,longest_len=0;
map<char,vector<unsigned long long> >char_pos_map;
for(int i=0;i<string_len;i++){
map<char,vector<unsigned long long> >::iterator char_pos_map_it=char_pos_map.find(s[i]);
if(char_pos_map_it==char_pos_map.end()) {
vector<unsigned long long> pos_list;
pos_list.push_back(i);
char_pos_map.insert(pair<char, vector<unsigned long long > >((char)s[i],pos_list));
} else {
vector<unsigned long long> & pos_list=char_pos_map_it->second;
pos_list.push_back(i);
}
} //map存储每个字符出现的位置
for(int index_head = 0;index_head<string_len;index_head++) {
std::map<char, vector<unsigned long long > >::iterator it = char_pos_map.find(s[index_head]);
if( it->second.size()==1) {
current_len = 1;
current_str = s[index_head];
if(current_len>longest_len) {
longest_str = current_str;
longest_len = current_len; //只出现一次的字符
}
} else {
vector<unsigned long long> & tmp_vec = it->second;
unsigned long long index_num = tmp_vec.size();
unsigned long long tmp_index_head = index_head;
for(long long j=(long long)(index_num-1);j>=0;j--) {
tmp_index_head = index_head;
unsigned long long tmp_index_tail = tmp_vec[j];
if(tmp_index_tail<tmp_index_head)
continue;
current_len = tmp_index_tail-tmp_index_head+1;
if( current_len==0 || current_len < longest_len)
continue;
current_str = s.substr(tmp_index_head, current_len); //取子字符串,验证是否为回文字符
while( ((long long)(tmp_index_tail-tmp_index_head)>=1) && (s[tmp_index_tail]==s[tmp_index_head]) ) {
tmp_index_head++;
tmp_index_tail--;
}
if( ((long long)(tmp_index_tail-tmp_index_head)==-1) || (tmp_index_tail-tmp_index_head==0) ){ //奇数 偶数个字符的情况
longest_len = current_len;
longest_str = current_str;
}
}
}
}
return longest_str;
}
};
2.2 动态规划
删除暴力解法中有很多重复的判断。很容易想到动态规划,时间复杂度O(n^2),空间O(n^2),动态规划方程如下:
- dp[i][j] 表示子串s[i…j]是否是回文
- 初始化:dp[i][i] = true (0 <= i <= n-1); dp[i][i-1] = true (1 <= i <= n-1); 其余的初始化为false
- dp[i][j] = (s[i] == s[j] && dp[i+1][j-1] == true)
在动态规划中保存最长回文的长度及起点即可
|
|
class Solution {public: string longestPalindrome(string s) { const int len = s.size(); if(len <= 1)return s; bool dp[len][len]; //dp[i][j]表示s[i..j]是否是回文 memset(dp, 0, sizeof(dp)); //初始化为0 int resLeft = 0, resRight = 0; dp[0][0] = true; for(int i = 1; i < len; i++) { dp[i][i] = true; dp[i][i-1] = true; //这个初始化容易忽略,当k=2时要用到 } for(int k = 2; k <= len; k++) //外层循环:枚举子串长度 for(int i = 0; i <= len-k; i++) //内层循环:枚举子串起始位置 { if(s[i] == s[i+k-1] && dp[i+1][i+k-2]) { dp[i][i+k-1] = true; if(resRight-resLeft+1 < k) { resLeft = i; resRight = i+k-1; } } } return s.substr(resLeft, resRight-resLeft+1); }}; |
2.3 从中间向两边展开,时间复杂度O(n^2),空间O(1)
回文字符串显然有个特征是沿着中心那个字符轴对称。比如aha沿着中间的h轴对称,a沿着中间的a轴对称。那么aa呢?沿着中间的空字符''轴对称。所以对于长度为奇数的回文字符串,它沿着中心字符轴对称,对于长度为偶数的回文字符串,它沿着中心的空字符轴对称。对于长度为N的候选字符串,我们需要在每一个可能的中心点进行检测以判断是否构成回文字符串,这样的中心点一共有2N-1个(2N-1=N-1 + N)。检测的具体办法是,从中心开始向两端展开,观察两端的字符是否相同
class Solution {public: string longestPalindrome(string s) { const int len = s.size(); if(len <= 1)return s; int start, maxLen = 0; for(int i = 1; i < len; i++) { //寻找以i-1,i为中点偶数长度的回文 int low = i-1, high = i; while(low >= 0 && high < len && s[low] == s[high]) { low--; high++; } if(high - low - 1 > maxLen) { maxLen = high - low -1; start = low + 1; } //寻找以i为中心的奇数长度的回文 low = i- 1; high = i + 1; while(low >= 0 && high < len && s[low] == s[high]) { low--; high++; } if(high - low - 1 > maxLen) { maxLen = high - low -1; start = low + 1; } } return s.substr(start, maxLen); }};java
两侧比较:
public class LongestPalindromicSubString1 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(longestPalindrome1("babcbabcbaccba"));
}
public static String longestPalindrome1(String s) {
int maxPalinLength = 0;
String longestPalindrome = null;
int length = s.length();
// check all possible sub strings
for (int i = 0; i < length; i++) {
for (int j = i + 1; j < length; j++) {
int len = j - i;
String curr = s.substring(i, j + 1);
if (isPalindrome(curr)) {
if (len > maxPalinLength) {
longestPalindrome = curr;
maxPalinLength = len;
}
}
}
}
return longestPalindrome;
}
public static boolean isPalindrome(String s) {
for (int i = 0; i < s.length() - 1; i++) {
if (s.charAt(i) != s.charAt(s.length() - 1 - i)) {
return false;
}
}
return true;
}
}
动态规划:
public class LongestPalindromicSubString2 {
public static String longestPalindrome2(String s) {
if (s == null)
return null;
if(s.length() <=1)
return s;
int maxLen = 0;
String longestStr = null;
int length = s.length();
int[][] table = new int[length][length];
//every single letter is palindrome
for (int i = 0; i < length; i++) {
table[i][i] = 1;
}
printTable(table);
//e.g. bcba
//two consecutive same letters are palindrome
for (int i = 0; i <= length - 2; i++) {
//System.out.println("i="+i+" "+s.charAt(i));
//System.out.println("i="+i+" "+s.charAt(i+1));
if (s.charAt(i) == s.charAt(i + 1)){
table[i][i + 1] = 1;
longestStr = s.substring(i, i + 2);
}
}
System.out.println(longestStr);
printTable(table);
//condition for calculate whole table
for (int l = 3; l <= length; l++) {
for (int i = 0; i <= length-l; i++) {
int j = i + l - 1;
if (s.charAt(i) == s.charAt(j)) {
table[i][j] = table[i + 1][j - 1];
if (table[i][j] == 1 && l > maxLen)
longestStr = s.substring(i, j + 1);
} else {
table[i][j] = 0;
}
printTable(table);
}
}
return longestStr;
}
public static void printTable(int[][] x){
for(int [] y : x){
for(int z: y){
//System.out.print(z + " ");
}
//System.out.println();
}
//System.out.println("------");
}
public static void main(String[] args) {
System.out.println(longestPalindrome2("1263625"));//babcbabcbaccba
}
}
leetcode--5 Longest Palindromic Substring的更多相关文章
- leetcode 第五题 Longest Palindromic Substring (java)
Longest Palindromic Substring Given a string S, find the longest palindromic substring in S. You may ...
- leetcode第五题--Longest Palindromic Substring
Problem:Given a string S, find the longest palindromic substring in S. You may assume that the maxim ...
- Leetcode:【DP】Longest Palindromic Substring 解题报告
Longest Palindromic Substring -- HARD 级别 Question SolutionGiven a string S, find the longest palindr ...
- LeetCode(5)Longest Palindromic Substring
题目 Given a string S, find the longest palindromic substring in S. You may assume that the maximum le ...
- [LeetCode] Longest Palindromic Substring 最长回文串
Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...
- Leetcode Longest Palindromic Substring
Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...
- 求最长回文子串 - leetcode 5. Longest Palindromic Substring
写在前面:忍不住吐槽几句今天上海的天气,次奥,鞋子里都能养鱼了...裤子也全湿了,衣服也全湿了,关键是这天气还打空调,只能瑟瑟发抖祈祷不要感冒了.... 前后切了一百零几道leetcode的题(sol ...
- LeetCode 5 Longest Palindromic Substring(最长子序列)
题目来源:https://leetcode.com/problems/longest-palindromic-substring/ Given a string S, find the longest ...
- 【JAVA、C++】LeetCode 005 Longest Palindromic Substring
Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...
随机推荐
- select下拉框如何与接口配合动态生成option选项
前几天在做任务时考虑到这个问题,具体任务用例如下: HTML: JS:
- thinkphp5.1跨模块调用控制器或者模型
tp5.1 采用命名空间的方式进行调用.
- tomcat memecached session 共享同步问题的解决
事件缘由:一个主项目“图说美物”,另外一个子功能是品牌商的入驻功能,是跟主项目分开的项目,为了共享登录的用户信息,而实现session共享,俩个tomcat,一个tomcat6,一个tomcat7 w ...
- rgb值转换成16进制
由于jQuery获取css中的background有时候是rgb值,所以往往需要一个转换函数. 以前觉得难,还写个博客记录,现在觉得好容易. let testColor = "rgb(20, ...
- Codeforces 350D(计算几何)
要点 用A.B.C一般式确定每条直线 将合法的圆心中点存到每条直线所属的vector中 枚举所有线段,二分后\(O(1)\)得到其中存在多少答案,累加 #include <cstdio> ...
- arch安装问题总结
安装 archLinux 的时候遇到的一些问题,记录下来方便以后安装. 1.fcitx 在设置/etc/locale.conf文件时,中文不能写成zh_CN.utf-8,而是要写成zh_CN.utf8 ...
- 【Unity3D/C#】利用IEnumerable<>和yield产生斐波那契数列
using UnityEngine; using System.Collections; using System.Collections.Generic; public class YieldTes ...
- Python 将IP转换为int
import socket import struct if __name__ == '__main__': ip = '127.0.0.1' int_ip = struct.unpack('!I', ...
- cgkib动态代理详解-不依赖接口,速度快
1. cglib原理-不依赖接口,速度快 使用ASM字节框架动态生成要代理类的子类,子类重写final以外的方法,织入横切逻辑 2. 示例-实现MethodInterceptor Test.java ...
- pat1085. Perfect Sequence (25)
1085. Perfect Sequence (25) 时间限制 300 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CAO, Peng Give ...