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的更多相关文章

  1. leetcode 第五题 Longest Palindromic Substring (java)

    Longest Palindromic Substring Given a string S, find the longest palindromic substring in S. You may ...

  2. leetcode第五题--Longest Palindromic Substring

    Problem:Given a string S, find the longest palindromic substring in S. You may assume that the maxim ...

  3. Leetcode:【DP】Longest Palindromic Substring 解题报告

    Longest Palindromic Substring -- HARD 级别 Question SolutionGiven a string S, find the longest palindr ...

  4. LeetCode(5)Longest Palindromic Substring

    题目 Given a string S, find the longest palindromic substring in S. You may assume that the maximum le ...

  5. [LeetCode] Longest Palindromic Substring 最长回文串

    Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...

  6. Leetcode Longest Palindromic Substring

    Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...

  7. 求最长回文子串 - leetcode 5. Longest Palindromic Substring

    写在前面:忍不住吐槽几句今天上海的天气,次奥,鞋子里都能养鱼了...裤子也全湿了,衣服也全湿了,关键是这天气还打空调,只能瑟瑟发抖祈祷不要感冒了.... 前后切了一百零几道leetcode的题(sol ...

  8. LeetCode 5 Longest Palindromic Substring(最长子序列)

    题目来源:https://leetcode.com/problems/longest-palindromic-substring/ Given a string S, find the longest ...

  9. 【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 ...

随机推荐

  1. Spring第一天:Spring的概述、SpringIOC入门(XML)、Spring的Bean管理、Spring属性注入

    记得引入约束 上图路径. 此时 只需修改配置文件 便可以随意更换实现类 无需修改代码. 传统方法必须用实现类(不面向接口了)来调用方法设置属性. 而在Spring中:在创建类的过程中发现实现类有nam ...

  2. vue中通过cross-env插件配置三种环境(开发,测试,生产)打包,不用切换api

    1. 话不多说,第一步就是安装必要的插件 npm install cross-env --save 2.修改config里面的参数,这里只展示一个test,其他类似 3.修改package.json ...

  3. CodeForces 114B 【STL应用】

    思路: 原来string类能sort 和 swap....太强了.... 注意:字典序最小输出,因为某个地方写挫了,sort了n发,代码挫. #include <bits/stdc++.h> ...

  4. Ckeditor 4 复制粘贴截图并转化base64格式保存至数据库

    虽然Ckeditor 中自带的有上传图片和文件的功能,但是有时候我们并不需要把图片保存至服务器的文件夹中. 反而是截图复制粘贴,把图片转化为base64格式保存在数据库中即可满足要求. 1.首先下载安 ...

  5. 《算法竞赛进阶指南》1.4Hash

    137. 雪花雪花雪花 有N片雪花,每片雪花由六个角组成,每个角都有长度. 第i片雪花六个角的长度从某个角开始顺时针依次记为ai,1,ai,2,-,ai,6. 因为雪花的形状是封闭的环形,所以从任何一 ...

  6. sql server 查询练习

    需要建的四个表: 学生表 create table Student ( Sno varchar(20) not null primary key, Sname varchar(20) not null ...

  7. PAT甲级——1098 Insertion or Heap Sort (插入排序、堆排序)

    本文同步发布在CSDN:https://blog.csdn.net/weixin_44385565/article/details/90941941 1098 Insertion or Heap So ...

  8. Qt学习之网络编程(一)

    一些说明 学了有一段时间的python了,小项目做了不少,最近由于项目需要,所以要回归老本行了,开始重点突击C++和qt.python的网络爬虫系列有时间就更吧. 获取本机网络信息 在网络应用中,经常 ...

  9. 平衡树合集(Treap,Splay,替罪羊,FHQ Treap)

    今天翻了翻其他大佬的博客,发现自己有些...颓废... 有必要洗心革面,好好学习 序:正常的BST有可能退化,成为链,大大降低效率,所以有很多方法来保持左右size的平衡,本文将简单介绍Treap,S ...

  10. python中深复制和浅复制区别

    在python中,对象赋值实际上是对象的的引用,当创建一个对象,然后把它赋值给另外一个变量的时候,python没有拷贝这个对象,而只是拷贝了这个对象的引用,多以就出现了浅复制,即复制后原对象改变后,复 ...