5:最长回文子串

问题描述

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

示例

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

输入: “cbbd”
输出: “bb”

思路

这题一个显而易见的思路就是取出所有的子串,然后去判定它是不是个回文串。但是这样时间复杂度太高了。(方法一)
还有就是可以认定一个字符/二个字符是回文串的中心,向两边扩展。这样可以被动剪枝。 (方法二)
还有就是动态规划了。(方法三)

方法一并不能AC,所以我们就不写了。我们只写方法二和方法三。

方法二

class Solution {
    public String longestPalindrome(String s) {
        if(s == null || s.length() == 0) return "";
        String res = "";
        char[] arr = s.toCharArray();
        for(int i = 0; i < arr.length; i++){
            String tmp = getTmpRes(arr, i);
            if(tmp.length() > res.length()) res = tmp;
        }
        return res;
    }
    private String getTmpRes(char[] arr, int mid){
        String option1 = single(arr,mid);
        String option2 = Double(arr,mid);
        return option1.length()>option2.length()?option1:option2;
    }
    // 处理中心字符为1个字符的情况
    private String single(char[] arr, int mid){
        int left = mid-1, right = mid + 1;
        while(left>-1&&right<arr.length&&arr[left]==arr[right]){
            left--;right++;
        }
        StringBuilder sb = new StringBuilder();
        for(int i = left+1; i < right; i++) sb.append(arr[i]);
        return sb.toString();
    }
    // 处理中心字符为2个字符的情况
    private String Double(char[] arr, int midLeft){
        int midRight = midLeft+1;
        while(midLeft>-1&&midRight<arr.length&&arr[midLeft]==arr[midRight]){
            midLeft--;midRight++;
        }
        StringBuilder sb = new StringBuilder();
        for(int i = midLeft+1; i < midRight; i++) sb.append(arr[i]);
        return sb.toString();
    }
}

注意,在这种边界条件比较复杂的题目当中,我们要充分运用模块化、函数化的编程思想来降低时间复杂度。一个函数只做一件事,有利于我们集中精力思考边界条件。

你可能感兴趣的:(leetcode中等题)