LeetCode5.最长回文子串

题目描述

给你一个字符串 s,找到 s 中最长的回文子串。

算法思路

动态规划:
讨论:
所有的单个字母是回文子串。
字母个数从2开始,使用dp。当数组的第i个数值和第j个字母相同,二维数组dp记录为true。接着判断当前子串的子串外层,即第i+1个位置和第j-1个位置的字母是否相同,以此递归。同时更新所得子串最大长度。
中心扩散法:
设置左右指针,遍历每一个字母。
讨论:如果左指针指向的字母和当前i位置的字母相同就左移,长度加一,继续左移。
右侧同样。
左指针指向的字母和右指针指向的字母相同,长度加二,同时进行左移和右移。

示例代码

动态规划:

class Solution {
    public String longestPalindrome(String s) {
        int len = s.length();
        //特殊处理
        if (len < 2) {
            return s;
        } 

        boolean[][] dp = new boolean[len][len];
        int begin = 0;//左边界
        int maxLen = 1;//符合要求子串长度

        for (int i = 0; i < len; i++) {
            dp[i][i] = true;
        }

        char[] charArray = s.toCharArray();
        //分情况讨论子串长度
        for (int L = 2; L <= len; L++) {
            for (int i = 0; i < len; i++) {
                int j = L + i - 1;
                //右边界出界
                if (j >= len) {
                    break;
                } 
                //对当下子串的子串进行判断
                if (charArray[i] != charArray[j]) {
                dp[i][j] = false;
                } else {
                    if (j - i < 3) {
                        dp[i][j] = true;
                    } else {
                        dp[i][j] = dp[i + 1][j - 1];
                    }
                }
                if (dp[i][j] && j - i + 1 > maxLen) {
                maxLen = j - i + 1;
                begin = i;
                }
            }
        }
        return s.substring(begin , begin + maxLen);
    }
}

时间复杂度:O(n²),n是字符串长度。动态规划的状态总数为O(n²),每个状态转移的时间为 O(1)。
空间复杂度:O(n²),存储每个状态所需要的总空间。
中心扩散法:

public String longestPalindrome(String s) {

        if (s == null || s.length() == 0) {
            return "";
        }
        int strLen = s.length();
        int left = 0;
        int right = 0;
        int len = 1;
        int maxStart = 0;
        int maxLen = 0;

        for (int i = 0; i < strLen; i++) {
            left = i - 1;
            right = i + 1;
            while (left >= 0 && s.charAt(left) == s.charAt(i)) {
                len++;
                left--;
            }
            while (right < strLen && s.charAt(right) == s.charAt(i)) {
                len++;
                right++;
            }
            while (left >= 0 && right < strLen && s.charAt(right) == s.charAt(left)) {
                len = len + 2;
                left--;
                right++;
            }
            if (len > maxLen) {
                maxLen = len;
                maxStart = left;
            }
            len = 1;
        }
        return s.substring(maxStart + 1, maxStart + maxLen + 1);

    }

时间复杂度:O(n²)。
空间复杂度:O(1)。

你可能感兴趣的:(动态规划,算法,leetcode)