LeetCode:最长回文字符串

LeetCode:最长回文字符串

No.5 最长回文字符串

利用公共子串、动态规划查询字符串的最长回文子串

题目:

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

示例 1:

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

示例 2:

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

解法:

  1. 列举法

    列举字符串并判断是否回文

    时间复杂度:\(O(n^3)\)

    空间复杂度:\(O(1)\)

    class Solution
    {
        public String longestPalindrome(String s)
        {
            int len = s.length();
            int max = 0;
            String ans = "";
            for (int i = 0; i < len; i++)
            {
                for (int j = i + 1; j <= len; j++)
                {
                    String str = s.substring(i, j);
                    if (isPalindromic(str) && str.length() > max)
                    {
                        max = Math.max(max, str.length());
                        ans = str;
                    }
                }
            }
            return ans;
        }
    
        public boolean isPalindromic(String s)
        {
            int len = s.length();
            for (int i = 0; i < len / 2; i++)
            {
                if (s.charAt(i) != s.charAt(len - i - 1))
                {
                    return false;
                }
            }
            return true;
        }
    }
    
  2. 公共子串、动态规划

    扫描二维码关注公众号,回复: 9797905 查看本文章

    时间复杂度:\(O(n^2)\)

    空间复杂度:\(O(n^2)\)

class Solution
{
   
    public String longestPalindrome(String s)
    {
        if (s.equals(""))
        {
            return "";
        }
        String origin = s;
        String reverse = new StringBuffer(s).reverse().toString();//字符串倒置
        int length = s.length();
        int[][] arr = new int[length][length];
        int maxLen = 0;
        int maxEnd = 0;
        for (int i = 0; i < length; i++)
        {
            for (int j = 0; j < length; j++)
            {
                if (origin.charAt(i) == reverse.charAt(j))
                {
                    if (i == 0 || j == 0)
                    {
                        arr[i][j] = 1;
                    }
                    else
                    {
                        arr[i][j] = arr[i - 1][j - 1] + 1;
                    }
                }
                if (arr[i][j] > maxLen)
                {
                    int beforeRev = length - 1 - j;
                    if (beforeRev + arr[i][j] - 1 == i)
                    { //判断下标是否对应
                        maxLen = arr[i][j];
                        maxEnd = i;
                    }
                }
            }
        }
        return s.substring(maxEnd - maxLen + 1, maxEnd + 1);
    }
}
  1. 中心扩散

    长度分偶数和奇数,每个位置两种遍历方式

    时间复杂度:\(O(n^2)\)

    空间复杂度:\(O(1)\)

    class Solution
    {
        public String longestPalindrome(String s)
        {
            int sLen = s.length();
            if (sLen < 2) return s;
            int start = 0, end = 0;
            for (int i = 0; i < sLen; i++)
            {
                int len1 = getLength(s, i, i);
                int len2 = getLength(s, i, i + 1);
                int maxLen = Math.max(len1, len2);
                if (maxLen > end - start + 1)
                {
                    start = i - (maxLen - 1) / 2;
                    end = i + maxLen / 2;
                }
            }
            return s.substring(start, end + 1);
        }
    
        public int getLength(String s, int l, int r)
        {
            int len = s.length();
            while (l >= 0 && r < len && s.charAt(l) == s.charAt(r))
            {
                l--;
                r++;
            }
            return r - l - 1;//开区间内的字符数=右-左-1
        }
    }

猜你喜欢

转载自www.cnblogs.com/pgjett/p/12455700.html