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. Redis学习笔记(一):基础数据结构

    一. 引言 <Redis设计与实现>一书主要分为四个部分,其中第一个部分主要讲的是Redis的底层数据结构与对象的相关知识. Redis是一种基于C语言编写的非关系型数据库,它的五种基本对 ...

  2. Docker 企业级镜像仓库 Harbor 的搭建与维护

    目录 一.什么是 Harbor 二.Harbor 安装 2.1.Harbor 安装环境 2.2.Harbor安装 2.3 配置HTTPS 三.Harbor 的使用 3.1.登录Harbor并使用 3. ...

  3. webpack@3.6.0(1) -- 快速开始

    本篇内容 前言 配置入口和输出 热更新 loader配置 js代码压缩 html的打包与发布 前言 //全局安装 npm install -g webpack(3.6.0) npm init //安装 ...

  4. Machine Learning-KNN

    思路:如果一个样本在特征空间中的k个最相近的样本中大多数属于某个类别,则该样本也属于该类别: 这段话中涉及到KNN的三要素:K.距离度量.决策规则 K:KNN的算法的结果很大程度取决于K值的选择: I ...

  5. 洛谷P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows

    P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows 题目描述 Each of Farmer John's N (4 <= N <= 16) cows has a u ...

  6. C语言经典算法100例(三)

    1.河内之塔 说明河内之塔(Towers of Hanoi)是法国人M.Claus(Lucas)于1883年从泰国带至法国的,河内为越战时北越的首都,即现在的胡志明市:1883年法国数学家 Edoua ...

  7. Unity---UNet学习(2)----简单mmo游戏实现

    1.实现步骤 新建空物体Controller,添加Network Manager.HUD组件. 创建Player模型,添加Inentity组件. Player添加脚本控制移动,只有当为本地用户才执行. ...

  8. thinkphp5加密解密

    thinkphp5目前没有提供加密解密类,但是tp3.2中提供了好几种加密解密方法,我们可以吧3.2的这些类拿来使用. 1.将tp3.2中ThinkPHP\Library\Think的Crypt文件夹 ...

  9. docker镜像的分层结构三

    docker的镜像分层 docker里的镜像绝大部分都是在别的镜像的基础上去进行创建的,也就是使用镜像的分层结构. 实验 比如说使用dockerfile去创建一个最简单的hello镜像.创建好对应的d ...

  10. 客户端发送http

    package com.scok; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStr ...