LeetCode 5. Longest Palindromic Substring题解

文章目录

  • 题目
    • 5. Longest Palindromic Substring
  • 分析
    • 思路一:动态规划
    • 思路二:(从中央位置开始)双向扩展扫描
  • 题解
    • 思路一Java实现
    • 思路二Java实现

题目

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.
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

Example 1:

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

Example 2:

Input: "cbbd"
Output: "bb"

分析

思路一:动态规划

定义状态:
       dp[i][j]:从index=i到index=j(包括i,j)的一段子串是否是回文串;
       dp[i][j] = true:是回文串;
       dp[i][j] = false:不是回文串。

定义转移方程:
       dp[i][j] = (s[i] == s[j] && dp[i+1][j-1]) (条件:i+1 <= j-1)
       dp[i][j] = s[i] == s[j] (条件:i+1 > j-1)

定义初始值:
       dp[s.length()-1][s.length()-1] = true;

思路二:(从中央位置开始)双向扩展扫描

对于串s的长度,分为奇数与偶数两种情况来考虑:
       奇数情况下,中心位置是一个字符;
       偶数情况下,中心位置是两个字符之间的间隙。

实现思路:从头开始遍历字符串s的每个字符,找到所有可作中心点的位置,对每个位置进行一次“双向扩展扫描”,找到以该位置为中心的最长回文子串。

题解

思路一Java实现

public class Solution {

    public String longestPalindrome(String s) {
        int length = s.length();

        //处理字符串为空的特殊情况
        if(length<1)return "";

        //存储最长的回文子串的起始结束位置(两端包含)
        int maxBegin = 0;
        int maxEnd = 0;

        //要返回的最长子串
        String longestPalindrome = "";

        boolean dp[][] = new boolean[length+1][length];

        //设置初始值
        dp[length-1][length-1] = true;

        for(int begin=length-1;begin>=0;begin--){
            for(int end=length-1;end>=begin;end--){

                //转移方程
                if(s.charAt(begin)==s.charAt(end)){
                    if(end-1<=begin+1 || dp[begin+1][end-1]){
                        dp[begin][end] = true;
                        //System.out.println("dp[" + i + "][" + j + "] = true");

                        //与目前已经记录下来的最长子串作对比(取相对更长的那一个)
                        if(end-begin>maxEnd-maxBegin){
                            maxBegin = begin;
                            maxEnd = end;
                        }
                        continue;
                    }
                    dp[begin][end] = false;
                    //System.out.println("dp[" + i + "][" + j + "] = false");
                }
            }
        }
        return s.substring(maxBegin,maxEnd+1);
    }

//    public static void main(String[] args) {
//        System.out.println(new Solution().longestPalindrome("cbbd"));
//    }
}

思路二Java实现

public class Solution2 {

    public String longestPalindrome(String s) {
        String longestPalindrome = "";
        for (int i = 0; i < s.length(); i++) {
            //奇数情况
            int pre = i;
            int next = i;
            String s1 = getLongestPalindromeByIndex(pre, next, s);
            //偶数情况
            next++;
            String s2 = getLongestPalindromeByIndex(pre, next, s);
            s1 = s1.length() > s2.length() ? s1 : s2;
            longestPalindrome = longestPalindrome.length() >= s1.length() ? longestPalindrome : s1;
        }
        return longestPalindrome;
    }

    public static String getLongestPalindromeByIndex(int pre, int next, String s) {
        while (pre >= 0 && next < s.length() && s.charAt(pre) == s.charAt(next)) {
            pre--;
            next++;
        }
        //当退出循环时,说明当前pre和next不相等,从pre+1截取到next-1
        return s.substring(pre + 1, next);
    }
}

你可能感兴趣的:(LeetCode)