LeetCode 题解之 5. Longest Palindromic Substring

5. Longest Palindromic Substring

题目描述和难度

  • 题目描述:

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设?s 的最大长度为1000。

示例 1:

输入: "babad"输出: "bab"注意: "aba"也是一个有效答案。

示例 2:

输入: "cbbd"输出: "bb"

思路1:中心扩散法:枚举回文串的中心(注意分回文串是奇数还是偶数时候的判断,可以同一设计一个方法),得到回文串,从中统计中最长的回文串即可。

思路2:动态规划方法。

思路3:专门解决回文串的一个著名算法 Manacher 算法。

参考解答

参考解答1:中心扩散法

public class Solution {

    public String longestPalindrome(String s) {
        int len = s.length();
        if (len == 0) {
            return "";
        }
        int longestPalindrome = 1;
        String longestPalindromeStr = s.substring(0, 1);
        for (int i = 0; i < len; i++) {
            String palindromeOdd = centerSpread(s, len, i, i);
            String palindromeEven = centerSpread(s, len, i, i + 1);
            String maxLen = palindromeOdd.length() > palindromeEven.length() ? palindromeOdd : palindromeEven;
            if (maxLen.length() > longestPalindrome) {
                longestPalindrome = maxLen.length();
                longestPalindromeStr = maxLen;
            }
        }
        return longestPalindromeStr;
    }

    private String centerSpread(String s, int len, int left, int right) {
        int l = left;
        int r = right;
        while (l >= 0 && r < len && s.charAt(l) == s.charAt(r)) {
            l--;
            r++;
        }
        // 这里要特别小心,跳出 while 循环的时候,是第 1 个满足 s.charAt(l) != s.charAt(r) 的时候
        // 所以,不能取 l,不能取 r
        return s.substring(l + 1, r);
    }
}

参考解答2:动态规划

public class Solution2 {

    public String longestPalindrome(String s) {
        int len = s.length();
        if (len == 0) {
            return "";
        }
        int longestPalindrome = 1;
        String longestPalindromeStr = s.substring(0, 1);
        boolean[][] dp = new boolean[len][len];
        // abcdedcba
        //   j   i
        // 如果 dp[j,i] = true 那么 dp[j+1,i-1] 也一定为 true
        // [j+1,i-1] 一定要构成至少两个元素额区间( 1 个元素的区间,s.charAt(i)==s.charAt(j) 已经判断过了)
        // 即 j+1 < i-1,即 i > j + 2 (不能取等号,取到等号,就退化成 1 个元素的情况了)
        // 应该反过来写
        for (int i = 0; i < len; i++) {
            for (int j = 0; j <= i; j++) {
                // 区间应该慢慢放大
                if (s.charAt(i) == s.charAt(j) && (i <= j + 2 || dp[j + 1][i - 1])) {
                    // 写成 dp[j][i] 就大错特错了,不要顺手写习惯了
                    dp[j][i] = true;
                    if (i - j + 1 > longestPalindrome) {
                        longestPalindrome = i - j + 1;
                        longestPalindromeStr = s.substring(j, i + 1);
                    }
                }
            }
        }
        return longestPalindromeStr;
    }
}

参考解答3:使用 Manacher 算法

/**
 * 使用 Manacher 算法
 */
public class Solution3 {

    /**
     * 创建分隔符分割的字符串
     *
     * @param s      原始字符串
     * @param divide 分隔字符
     * @return 使用分隔字符处理以后得到的字符串
     */
    private String generateSDivided(String s, char divide) {
        int len = s.length();
        if (len == 0) {
            return "";
        }
        if (s.indexOf(divide) != -1) {
            throw new IllegalArgumentException("参数错误,您传递的分割字符,在输入字符串中存在!");
        }
        StringBuilder sBuilder = new StringBuilder();
        sBuilder.append(divide);
        for (int i = 0; i < len; i++) {
            sBuilder.append(s.charAt(i));
            sBuilder.append(divide);
        }
        return sBuilder.toString();
    }

    public String longestPalindrome(String s) {
        int len = s.length();
        if (len == 0) {
            return "";
        }
        String sDivided = generateSDivided(s, '#');
        int slen = sDivided.length();
        int[] p = new int[slen];
        int mx = 0;
        // id 是由 mx 决定的,所以不用初始化,只要声明就可以了
        int id = 0;
        int longestPalindrome = 1;
        String longestPalindromeStr = s.substring(0, 1);
        for (int i = 0; i < slen; i++) {
            if (i < mx) {
                // 这一步是 Manacher 算法的关键所在,一定要结合图形来理解
                // 这一行代码是关键,可以把两种分类讨论的情况合并
                p[i] = Integer.min(p[2 * id - i], mx - i);
            } else {
                // 走到这里,只可能是因为 i = mx
                if (i > mx) {
                    throw new IllegalArgumentException("程序出错!");
                }
                p[i] = 1;
            }
            while (i - p[i] >= 0 && i + p[i] < slen && sDivided.charAt(i - p[i]) == sDivided.charAt(i + p[i])) {
                p[i]++;
            }
            // 我们想象 mx 的定义,它是遍历过的 i 的 i + p[i] 的最大者
            // 写到这里,我们发现,如果 mx 的值越大,
            // 进入上面 i < mx 的判断的可能性就越大,这样就可以重复利用之前判断过的回文信息了
            if (i + p[i] > mx) {
                mx = i + p[i];
                id = i;
            }

            if (p[i] - 1 > longestPalindrome) {
                longestPalindrome = p[i] - 1;
                longestPalindromeStr = sDivided.substring(i - p[i] + 1, i + p[i]).replace("#", "");
            }
        }
        return longestPalindromeStr;
    }
}

本篇文章的地址为 https://liweiwei1419.github.io/leetcode-solution/leetcode-0005-longest-palindromic-substring ,如果我的题解有错误,或者您有更好的解法,欢迎您告诉我 [email protected] 。

.label-warning { background-color: #f0ad4e; } .label-success { background-color: #5cb85c; } .label-danger { background-color: #d9534f; } .label { display: inline; padding: .2em .6em .3em; font-size: 75%; font-weight: 700; line-height: 1; color: #fff; text-align: center; white-space: nowrap; vertical-align: baseline; border-radius: .25em; }

原文地址:https://www.cnblogs.com/liweiwei1419/p/9203222.html

时间: 2024-10-10 00:09:03

LeetCode 题解之 5. Longest Palindromic Substring的相关文章

LeetCode【5】. Longest Palindromic Substring --java实现

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, and there exists one unique longest palindromic substring. 题目要求给定字符串的最大对称子字符串,如"aaabccbac

leetcode第五题--Longest Palindromic Substring

Problem: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. 找出最大的回文子串,回文就是指字符串倒过来和之前的一样.例如aba  倒过来还是aba.abac中的最大回文子串就是aba. 我一开始

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

Longest Palindromic Substring -- HARD 级别 Question SolutionGiven 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. 经典的DP题目. 主页君给出3种解

LeetCode(3)题解: Longest Palindromic Substring

https://leetcode.com/problems/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, and there exists one unique longest palindromic substring. 思路: 我的思路是遍

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, and there exists one unique longest palindromic substring. 在给定一个字符串S中,找到最长的回文串. 很恶心的一道题,不过应该都能想到枚举,从第一个开始枚举.枚举的字母向两头延伸,如果相同则继续,不同则开始下一

Longest Palindromic Substring leetcode java

题目: 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. 题解: 第一种方法就是挨个检查,维护全局最长,时间复杂度为O(n3),会TLE. 代码如下: 1 public String longestP

LeetCode #5 Longest Palindromic Substring (M)

[Problem] 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. [Analysis] 这题的思路有很多种,网上也有各种讨论.这里我采用的是个人觉得比较好理解的一种利用Dynamic Progra

LeetCode(4) || Longest Palindromic Substring 与 Manacher 线性算法

LeetCode(4) || Longest Palindromic Substring 与 Manacher 线性算法 题记 本文是LeetCode题库的第五题,没想到做这些题的速度会这么慢,工作之余全部耗在这上面了,只怪自己基础差.本文主要介绍使用Manacher线性算法来求解字符串的最长回文子字符串. 题目 Given a string S, find the longest palindromic substring in S. You may assume that the maxim

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

题目来源:https://leetcode.com/problems/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, and there exists one unique longest palindromic substring. 动态规划,类似于l