• 5.Longest Palindromic Substring---dp


    题目链接:https://leetcode.com/problems/longest-palindromic-substring/description/

    题目大意:找出最长回文子字符串(连续)。

    法一:暴力,三层for循环,超时。代码如下:

     1 public String longestPalindrome(String s) {
     2         String res = "";
     3         //逐一检查每个子字符串
     4         for(int i = 0; i < s.length(); i++) {
     5             for(int j = i + 1; j < s.length(); j++) {
     6                 String tmp = s.substring(i, j + 1);
     7                 if(isPalindrome(tmp) == true) {
     8                     if(tmp.length() > res.length()) {
     9                         res = tmp;
    10                     }
    11                 }
    12             }
    13         }
    14         if(res.length() == 0) {
    15             res = String.valueOf(s.charAt(0));
    16         }
    17         return res;
    18     }
    19     //判断子字符串是否是回文
    20     public static boolean isPalindrome(String s) {
    21         for(int i = 0, j = s.length() - 1; i < j; i++, j--) {
    22             if(s.charAt(i) != s.charAt(j)) {
    23                 return false;
    24             }
    25         }
    26         return true;
    27     }
    View Code

    法二(借鉴):dp,依次计算长度为1,2,3,。。。n的所有子字符串是否是回文,只是每次计算的时候都可以直接沿用上一次计算的结果,这样可以不用for循环判断,也就是减少了一层for循环。dp公式:dp[i, j]=ture表示初始下标为i,终点下标为j的字符串是回文字符串,dp[i, j]=true当且仅当dp[i+1, j-1]=true。代码如下(耗时71ms):

     1     public String longestPalindrome(String s) {
     2         int length = s.length();
     3         boolean dp[][] = new boolean[length][length];
     4         int start = 0, maxLength = 1;
     5         //初始化回文长度是1-2
     6         for(int i = 0; i < length; i++) {
     7             dp[i][i] = true;
     8             if(i < length - 1 && s.charAt(i) == s.charAt(i + 1)) {
     9                 dp[i][i + 1] = true;
    10                 start = i;
    11                 maxLength = 2;
    12             }
    13         }
    14         //计算回文长度是3-length
    15         for(int strLength = 3; strLength <= length; strLength++) {
    16             //计算所有长度为strLength的字符串是否是回文串
    17             for(int i = 0; i <= length - strLength; i++) {
    18                 int j = i + strLength - 1;//子字符串终止位置
    19                 if(dp[i + 1][j - 1] == true && s.charAt(i) == s.charAt(j)) {
    20                     dp[i][j] = true;
    21                     start = i;
    22                     maxLength = strLength;
    23                 }
    24             }
    25         }
    26         return s.substring(start, start + maxLength);
    27     }
    View Code

    dp数组(例子:cabba计算回文):

      0("c") 1("a") 2("b") 3("b") 4("a")
    0("c") T(c) F(ca) F(cab) F(cabb) F(cabba)
    1("a")   T(a) F(ab) F(abb) T(abba)
    2("b")     T(b) T(bb) F(bba)
    3("b")       T(b) F(ba)
    4("a")         T(a)

    dp数组填充顺序:从左下到右上,即每一个数值计算都要用到左边,下边,左下的数据。

    法三(借鉴):中心扩展法(分治法),以每个字符为中心,向两边扩展找相应的字符串是否有回文。但是,要注意两种情况,一种是aba的情况,一种是abba的情况,两种的扩展中心有点区别。代码如下(耗时67ms):

     1     public String longestPalindrome(String s) {
     2         int length = s.length();
     3         int start = 0, maxLength = 1;
     4         //aba的情况,以i为中心扩展
     5         for(int i = 0; i < length; i++) {
     6             int left = i - 1, right = i + 1;
     7             while(left >= 0 && right < length && s.charAt(left) == s.charAt(right)) {
     8                 if(right - left + 1 > maxLength) {
     9                     maxLength = right - left + 1;
    10                     start = left;
    11                 }
    12                 left--;
    13                 right++;
    14             }
    15         }
    16         //abba的情况,以i, i+1为中心扩展
    17         for(int i = 0; i < length; i++) {
    18             int left = i, right = i + 1;
    19             while(left >= 0 && right < length && s.charAt(left) == s.charAt(right)) {
    20                 if(right - left + 1 > maxLength) {
    21                     maxLength = right - left + 1;
    22                     start = left;
    23                 }
    24                 left--;
    25                 right++;
    26             }
    27         }
    28         return s.substring(start, start + maxLength);
    29     }
    View Code
  • 相关阅读:
    C#中Dictionary的用法
    System.Timers.Timer用法
    C#中的异步调用及异步设计模式(三)——基于事件的异步模式
    C#中的异步调用及异步设计模式(二)——基于 IAsyncResult 的异步设计模式
    C#中的异步调用及异步设计模式(一)
    [你必须知道的异步编程]——异步编程模型(APM)
    strncasecmp与strcasecmp用法
    C语言之strrchr函数
    HDU 5289 Assignment (ST算法区间最值+二分)
    poj 1733 Parity game(种类并查集)
  • 原文地址:https://www.cnblogs.com/cing/p/8471882.html
Copyright © 2020-2023  润新知