• [LeetCode] 5. Longest Palindromic Substring


    Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

    Example 1:

    Input: "babad"
    Output: "bab"
    Note: "aba" is also a valid answer.
    

    Example 2:

    Input: "cbbd"
    Output: "bb"

    最长的回文子串。

    题意是给一个字符串,请输出其中最长的回文子串。

    这个题有两种做法,一个是中心扩散法,一个是DP。无论是DP还是中心扩散法,都需要注意两种不同的case,一种是aba,回文中间只有一个字母;另一种是abba,回文中间是两个字母的。

    首先是中心扩散法。思路是把每一个字母或者每一对字母都当做回文的中心,然后试着向外扩增。注意12行(JS)取substring的范围,为什么是left + 1是因为第8行while循环最后一次是true的时候,多执行了一次left--和right++,所以在退出while循环的时候left和right的位置都比回文的部分往外扩增了一步。但由于substring的右边界是开区间所以right部分不需要 + 1。

    时间O(n^2)

    空间O(1)

    JavaScript实现

     1 /**
     2  * @param {string} s
     3  * @return {string}
     4  */
     5 var longestPalindrome = function (s) {
     6     let res = '';
     7     var checkPalindrome = function (s, left, right) {
     8         while (left >= 0 && right < s.length && s[left] === s[right]) {
     9             left--;
    10             right++;
    11         }
    12         let cur = s.substring(left + 1, right);
    13         if (cur.length > res.length) {
    14             res = cur;
    15         }
    16     }
    17 
    18     if (s === null || s.length === 0) return '';
    19     for (let i = 0; i < s.length; i++) {
    20         checkPalindrome(s, i, i);
    21         checkPalindrome(s, i, i + 1);
    22     }
    23     return res;
    24 };

    Java实现

     1 class Solution {
     2     String res = "";
     3 
     4     public String longestPalindrome(String s) {
     5         // 注意数据范围,这里不需要判断字符串为空的corner case了
     6         for (int i = 0; i < s.length(); i++) {
     7             helper(s, i, i);
     8             helper(s, i, i + 1);
     9         }
    10         return res;
    11     }
    12 
    13     private void helper(String s, int left, int right) {
    14         while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
    15             left--;
    16             right++;
    17         }
    18         String cur = s.substring(left + 1, right);
    19         if (cur.length() > res.length()) {
    20             res = cur;
    21         }
    22     }
    23 }

    之后是DP的做法。既然是DP,就需要先得出小范围的解,然后再拓展到大范围的解。这里需要用到一个二维数组来记录DP的解。这里DP数组的定义是字符串[i, j]是否是回文。这是个闭区间。

    JS代码12行判断dp[i][j]的时候,一定要先判断j - i是否小于等于2,因为是要保证j在i的右侧,或者起码i和j要在同一个位置上,否则之后的判断(dp[i + 1][j - 1])是没有意义的。有一种回文的情况是aba类型的,如果此时i和j都在b的位置上,那么判断dp[i + 1][j - 1]是没有意义的。

    时间O(n^2)

    空间O(n^2)

    Java实现

     1 class Solution {
     2     public String longestPalindrome(String s) {
     3         if (s == null || s.length() == 0) {
     4             return s;
     5         }
     6         String res = "";
     7         boolean[][] dp = new boolean[s.length()][s.length()];
     8         int max = 0;
     9         for (int j = 0; j < s.length(); j++) {
    10             for (int i = 0; i <= j; i++) {
    11                 dp[i][j] = s.charAt(i) == s.charAt(j) && ((j - i <= 2) || dp[i + 1][j - 1]);
    12                 if (dp[i][j]) {
    13                     if (j - i + 1 > max) {
    14                         max = j - i + 1;
    15                         res = s.substring(i, j + 1);
    16                     }
    17                 }
    18             }
    19         }
    20         return res;
    21     }
    22 }

    JavaScript实现

     1 /**
     2  * @param {string} s
     3  * @return {string}
     4  */
     5 var longestPalindrome = function (s) {
     6     const m = s.length;
     7     const dp = [...new Array(m)].map(() => new Array(m).fill(false));
     8     let max = 0;
     9     let res = '';
    10     for (let j = 0; j < m; j++) {
    11         for (let i = 0; i <= j; i++) {
    12             dp[i][j] = s[i] === s[j] && ((j - i <= 2) || dp[i + 1][j - 1]);
    13             if (dp[i][j]) {
    14                 if (j - i + 1 > max) {
    15                     max = j - i + 1;
    16                     res = s.substring(i, j + 1);
    17                 }
    18             }
    19         }
    20     }
    21     return res;
    22 };

     

    相关题目

    5. Longest Palindromic Substring

    647. Palindromic Substrings

    LeetCode 题目总结

  • 相关阅读:
    Java的 Annotation 新特性
    Java 枚举
    Java 泛型
    Linux kali信息探测以及 Nmap 初体验
    静态导入 ()
    Java foreach循环
    Java 可变参数
    炫酷的CSS3响应式表单
    关于CSS选择器连续性的问题
    简述ECMAScript6新增特性
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12194816.html
Copyright © 2020-2023  润新知