最长回文子串

123 阅读1分钟

这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战

1.leetcode最长回文子串

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

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

示例 2:

输入:s = "cbbd"
输出:"bb"

示例 3:

输入:s = "a"
输出:"a"

方法1

暴力循环判断,双重循环获取每一个字符字串,判断每个字串是否回文串,判断记录下最长的回文串的位置,最后切割返回。

class Solution {
    public String longestPalindrome(String s) {
        int len = s.length();
        // 空串和一个字符的直接返回本身
        if (len < 2) {
            return s;
        }

        // 拆成数组 用数组下标来访问字符比较
        char[] chars = s.toCharArray();
        // 记录最长回文串的长度
        int maxLen = 1;
        // 记录最长回文串开始位置
        int p = 0;
        // 循环遍历判断每个子字符串
        for (int i = 0; i < len - 1; i++) {
            for (int j = i + 1; j < len; j++) {
                // 如果当前字符串是回文串且长度大于记录的回文串长度
                if (j - i + 1 > maxLen && hui(chars, i, j)) {
                    maxLen = j - i + 1;
                    p = i;
                }
            }
        }
        // 返回最长的回文串
        return s.substring(p, maxLen + p);
    }

    /**
     * 判断是否回文数
     *
     * @param chars 字符串
     * @param i     开始位置
     * @param j     结束位置
     * @return
     */
    private boolean hui(char[] chars, int i, int j) {
        while (i < j) {
            // 循环判断字符串两边元素,如果不等就不是回文串
            if (chars[i++] != chars[j--]) {
                return false;
            }
        }
        return true;
    }
}

方法2

还有一种方法,以一个字符串为坐标,向左右两边遍历,比较左右两个字符是否相等,直到遇到不相等的,那么在这之前的字符串就是回文串,但是需要考虑,起点的问题,比如aba,abba这种,有可能是以一个字符开始向两边查找,也有可能是以两个字符开始,所以都需要判断。以当前遍历的字符或者当前字符和下个字符开始,往左右两边扩散查找,找到一个回文串,判断之前的是否比记录的大,是则需要更新记录下目前最大的回文串的下标,直到查找完成,最后根据下标substring返回目标字符串。


public String longestPalindrome(String s) {
    // 记录最长的回文串 是长度的一半
    int maxLen = 0;
    int tempLen = 0;

    // 记录回文串的开始结束位置->[left,right)
    int left = 0;
    int right = 0;
    for (int i = 0; i < s.length(); i++) {
        // 长度比当前记录的大,就更新一下
        tempLen = huiWen(s, i, i);
        if (tempLen > maxLen) {
            maxLen = tempLen;
            left = i - (tempLen / 2);
            right = i + (tempLen / 2) + 1;
        }
        // 长度比当前记录的大,就更新一下
        tempLen = huiWen(s, i, i + 1);
        if (tempLen > maxLen) {
            maxLen = tempLen;
            left = i - ((tempLen / 2) - 1);
            right = i + (tempLen / 2) + 1;
        }

    }
    return s.substring(left, right);
}

/**
 * 返回回文串的半长,然后根据这个算出坐标。
 * @param s
 * @param i
 * @param j
 * @return
 */
public int huiWen(String s, int i, int j) {
    while (i >= 0 && j < s.length()) {
        if (s.charAt(i) != s.charAt(j)) {
            break;
        }
        i--;
        j++;
    }
    return j - (i + 1);
}