zoukankan      html  css  js  c++  java
  • 5. 最长回文子串

    方法一、DP

    假设dp[i][j]表示从i到j下标是否是回文串

    于是有dp[i][j]=dp[i+1][j-1]^(s[i]==s[j])

    时间O(n^2),空间O(n^2)

     1     public String longestPalindrome(String s) {
     2         int len = s.length();
     3         if(len<2){
     4             return s;
     5         }
     6         
     7         boolean dp[][] = new boolean[len][len];
     8         // 每个字符自身都是回文的
     9         for(int i=0;i<len;i++){
    10             dp[i][i]=true;
    11         }
    12         // 由于每个字符自身回文,因此最短也是1
    13         int maxLen = 1,begin=0;
    14         for(int j=1;j<len;j++){
    15             for(int i=0;i<j;i++){
    16                 // 首尾不相等,则必然不回文
    17                 if(s.charAt(i)!=s.charAt(j)){
    18                     dp[i][j]=false;
    19                 }else{
    20                     // 首尾相同的情况下,前后相差位数不超过2的时候,必然是回文的
    21                     if(j-i<3){
    22                         dp[i][j]=true;
    23                     }else{
    24                         // 这里可以由之前的状态获取到当前的状态
    25                         dp[i][j]=dp[i+1][j-1];
    26                     }
    27                 }
    28                 // 每次循环后更新最长回文子串的长度与起始位置
    29                  if(dp[i][j]==true && (j-i+1)>maxLen){
    30                     maxLen = j-i+1;
    31                     begin = i;
    32                 }              
    33             }           
    34         }
    35         return s.substring(begin,begin+maxLen);
    36     }

    方法二、中心拓展

    针对每个元素,我们以此为中心,使用双指针法向两边拓展。

    直到不回文为止,每次结束更新最长回文子串的长度与起始位置

    时间O(n^2),空间O(1)

     1 class Solution {
     2     public String longestPalindrome(String s) {
     3         int len=s.length();
     4         if(len<2){
     5             return s;
     6         }
     7 
     8         int start=0,end=0;
     9         for(int i=0;i<len;i++){
    10             // 需要考虑奇数和偶数2种情况
    11             int len_odd = expandCenter(s,i,i);
    12             int len_even = expandCenter(s,i,i+1);
    13             int maxLen = Math.max(len_odd,len_even);
    14             if(maxLen>end-start){
    15                 start = i-(maxLen-1)/2;
    16                 end = i+maxLen/2;
    17             }           
    18         }
    19         return s.substring(start,end+1);
    20     }
    21 
    22     public int expandCenter(String s,int left,int right){
    23         while(left>=0 && right<s.length() && s.charAt(left)==s.charAt(right)){
    24             left--;
    25             right++;
    26         }
    27         // 这里由于最后一次循环时start和end分别做了加减,所以是end-start-1+2=start-left-1
    28         return right-left-1;
    29     }
    30 }

    方法三、马拉车

    争取早日不再是一只菜鸡
  • 相关阅读:
    正则表达式把所有Paul替换成Ringo:Paul Puala Pualine paul Paul
    DOM 和 BOM
    新手的grid布局
    css中的单位和css中的颜色表示方法
    css定位
    Winform 通过 WebBrowser 与 JS 交互
    PDF目录编辑器使用介绍
    [.NET] 控制只启动单个指定外部程序
    搭建 Frp 来远程内网 Windows 和 Linux 机子
    CentOs8 nmcli命令行方式操作网卡配置
  • 原文地址:https://www.cnblogs.com/jchen104/p/14804246.html
Copyright © 2011-2022 走看看