寻找最大回文

package main.java.demo5;

/**
 * 给你一个字符串 s,找到 s 中最长的回文子串。
 */
public class LongestPalindrome {
    /**
     * 解法思路:从字符0开始直到最后一个字符,
     * 以该字符为中心向两边扩展,直到不能扩展为止.
     * 注意:这里要分最开始的时候是一项还是两项,比如aba和abba.
     *
     * @param s
     * @return
     */
    public String longestPalindrome_1(String s) {
        int length = s.length();
        int[] currentResult = new int[2];
        int[] result = new int[2];
        int leftPoint = 0;
        int rightPoint = 0;
        char[] chars = s.toCharArray();

        for (int i = 0; i < length - 1; i++) {
            // 初始时左指针和右指针都指向当前选中的字符
            leftPoint = rightPoint = i;
            // 分别调用回文中单个字符在中间和两个相等的字符在中间的算法,求出最大回文的起止位置
            int[] singleResult = getPalindrome(chars, leftPoint, rightPoint);
            int[] doubleResult = getPalindrome(chars, leftPoint, rightPoint + 1);
            // 比较当前位置中回文的最大长度作为currentLength代表当前位置回文最大值
            int singleLength = singleResult[1] - singleResult[0];
            int doubleLength = doubleResult[1] - doubleResult[0];
            currentResult = singleLength > doubleLength ? singleResult : doubleResult;
            // 根据当前最好结果和result比较并赋值,
            int resultLength = result[1] - result[0];
            int currentLength = currentResult[1] - currentResult[0];
            if (currentLength > resultLength) {
                result = currentResult;
            }
        }
        // 返回结果
        return s.substring(result[0], result[1] + 1);
    }

    private int[] getPalindrome(char[] chars, int leftPoint, int rightPoint) {
        int[] result = new int[2];
        while (leftPoint >= 0 && rightPoint < chars.length) {
            if (chars[leftPoint] == chars[rightPoint]) {
                result[0] = leftPoint;
                result[1] = rightPoint;
            } else {
                return result;
            }
            leftPoint--;
            rightPoint++;
        }
        return result;
    }

    /**
     * 解法思路: 利用动态规划解决此问题,
     *          递归方程为P(i,j) = P(i + 1, j - 1) && (Si == Sj)
     *          递归方程结束条件为 P(i,i) = true 或 P(i,i+1) = (Si == Sj)
     * @param s
     * @return
     */
    public String longestPalindrome_2(String s) {
        int length = s.length();
        int[] currentResult = new int[2];
        // 当字符串长度小于等于1时,直接返回
        if(length <= 1) {
            return s;
        }

        // 创建二维数组用于存储回文起止位置的结果
        boolean[][] result = new boolean[length][length];
        // 将字符串中字符数量为1设置为true
        for (int i = 0; i < length; i++) {
            result[i][i] = true;
        }

        char[] chars = s.toCharArray();
        // 对字符串进行遍历, 从字符数量为2 开始.
        for (int subLen = 2; subLen <= length; subLen++) {
            for (int leftPoint = 0; leftPoint < length - subLen + 1; leftPoint++) {
                int rightPoint = leftPoint + subLen - 1;
                if(chars[leftPoint] == chars[rightPoint]){
                    if(subLen == 2) {
                        result[leftPoint][rightPoint] = true;
                    } else {
                        result[leftPoint][rightPoint] = result[leftPoint + 1][rightPoint - 1];
                    }
                    if (result[leftPoint][rightPoint] == true) {
                        if (rightPoint - leftPoint > currentResult[1] - currentResult[0]) {
                            currentResult[0] = leftPoint;
                            currentResult[1] = rightPoint;
                        }
                    }
                }
            }
        }
        return s.substring(currentResult[0], currentResult[1] + 1);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值