牛客网编程高频题29——NC17最长回文子串

目录

最长回文子串

描述

示例1

方法一:动态规划

方法二:中心扩散法

方法三:暴力搜索


最长回文子串

描述

对于一个字符串,请设计一个高效算法,计算其中最长回文子串的长度。

给定字符串 以及它的长度 n,请返回最长回文子串的长度。

示例1

输入:

"abc1234321ab",12

返回值:

7

方法一:动态规划

我们用数组 dp[left][right] 来表示位于 left 和 right 之间的字符串是否为回文子串,那么我们就很容易得到递推关系式,

dp[left][right] = dp[left+1][right-1] && A.charAt(left)==A.charAt(right),

import java.util.*;

public class Solution {
    public int getLongestPalindrome(String A, int n) {
        // write code here
        if(n==0||n==1) return n;

        boolean dp[][]=new boolean[n][n];
        int maxLen=0;
        for (int right = 1; right < n; right++) {
            for (int left = 0; left < right; left++) {
                //若左右两个字符不同,则dp[left][right]一定为false
                if(A.charAt(left)!=A.charAt(right)) continue;

                //若左右两个字符相同,还要进一步判断
                //1.如果right-left<3(可取0,1,2),那么我们认为是回文字串,dp[left][right]=true
                //2.如果right-left>=3,需要根据dp[left+1][right-1]的真假来判断dp[left][right]
                if (right-left<3){
                    dp[left][right]=true;
                }else{
                    dp[left][right]=dp[left+1][right-1];
                }

                //保留最长的回文字串长度
                if (dp[left][right]==true){
                    maxLen=maxLen>right-left+1?maxLen:right-left+1;
                }
            }
        }
        return maxLen;
    }
}

方法二:中心扩散法

import java.util.*;

public class Solution {
    public int getLongestPalindrome(String A, int n) {
        // write code here
        int maxLen=1;
        for (int i = 0; i < n; i++) {
            if (n-i<=maxLen/2) break;

            int left=i-1,right=i+1;
            if(left>=0&&right<n){
                while (A.charAt(left)==A.charAt(i) && left-1>=0){
                    left=left-1;
                }
                while (A.charAt(right)==A.charAt(i) && right+1<n){
                    right=right+1;
                }
                while (A.charAt(left)==A.charAt(right)){
                    maxLen=maxLen>right-left+1?maxLen:right-left+1;
                    left=left-1;
                    right=right+1;
                    if (left<0 || right>=n) break;
                }
            }
        }
        return maxLen;
    }
}

该方法比动态规划时间消耗和空间消耗都要小得多,

方法三:暴力搜索

暴力搜索就是遍历所有的字串,然后判断是否是回文串,返回最大长度即可,

import java.util.*;

public class Solution {
    public int getLongestPalindrome(String A, int n) {
        // write code here
        if (n < 2)
            return n;

        int maxLen = 0;
        for (int i = 0; i < n - 1; i++) {
            for (int j = i; j < n; j++) {
                //截取所有子串,如果截取的子串小于等于之前遍历过的最大回文串,直接跳过
                if (j - i < maxLen)
                    continue;
                if (isPalindrome(A, i, j)) {
                    if (maxLen < j - i + 1) {
                        maxLen = j - i + 1;
                    }
                }
            }
        }
        return maxLen;
    }
    
    //判断是否是回文串
    private boolean isPalindrome(String s, int start, int end) {
        while (start < end) {
            if (s.charAt(start++) != s.charAt(end--))
                return false;
        }
        return true;
    }
}

时间消耗最慢,

猜你喜欢

转载自blog.csdn.net/weixin_39478524/article/details/117472395