LeetCode随缘刷题之最长回文子串

这一题我用的相对比较笨的方法。
相对于大佬们用的动态规划法,比较复杂。但却更容易理解,我主要是通过记录下标来确定最长回文串的。

package leetcode.day_12_06;

/**
 * 给你一个字符串 s,找到 s 中最长的回文子串。
 * <p>
 * <p>
 * 示例 1:
 * <p>
 * 输入:s = "babad"
 * 输出:"bab"
 * 解释:"aba" 同样是符合题意的答案。
 * 示例 2:
 * <p>
 * 输入:s = "cbbd"
 * 输出:"bb"
 * 示例 3:
 * <p>
 * 输入:s = "a"
 * 输出:"a"
 * 示例 4:
 * <p>
 * 输入:s = "ac"
 * 输出:"a"
 *
 * @author soberw
 * @Classname LongestPalindrome0005
 * @Description
 * @Date 2021-12-06 12:39
 */
public class LongestPalindrome0005 {
    /**
     * @param s 需要查找的字符串
     * @description: 找到 s 中最长的回文子串。
     * @return: 最长回文子串
     * @author: soberw
     * @time: 2021/12/6 12:40
     */
    public String longestPalindrome(String s) {
        //直接返回
        if (s.length() == 0 || s.length() == 1) {
            return s;
        }
        int len = s.length();
        //定义回文子串的起止下标
        int start = 0;
        int end = 0;
        //定义两个指针(头尾)
        int left = 0;
        int right = 0;
        for (int i = 0; i < len; i++) {
            left = i;
            right = i;
            //从当前位置开始,判断尾指针后面的字符是否与当前所指相等,相等继续向后比较
            //旨在找到连续字符
            while (right < len - 1 && s.charAt(right) == s.charAt(right + 1)) {
                right++;
            }
            //在连续字符的基础上,判断其前一个是否和后一个相等,以此类推
            while (left > 0 && right < len - 1 && s.charAt(left - 1) == s.charAt(right + 1)) {
                left--;
                right++;
            }
            //始终保持start和end是最大的范围
            if ((end - start) < (right - left)) {
                start = left;
                end = right;
            }
        }
        return s.substring(start, end + 1);
    }

    public static void main(String[] args) {
        System.out.println(new LongestPalindrome0005().longestPalindrome("babad"));
        System.out.println(new LongestPalindrome0005().longestPalindrome("cbbd"));
        System.out.println(new LongestPalindrome0005().longestPalindrome(""));
        System.out.println(new LongestPalindrome0005().longestPalindrome("a"));
    }
}

运行结果:
在这里插入图片描述
在这里插入图片描述
可能上面的解释还比较笼统,下面我画图演示一下执行流程:
例一:输入"bbbbb”:
在这里插入图片描述

刚开始left=0,right=0
程序进入第一个while循环,且满足条件,因为s[0]=s[1]=“b”,所以right++
向后走发现继续相等,就一直向后,直到不满足条件退出
此时right = len - 1
不满足第二个循环条件(其实就是right走到头了)

就这样进行下去,保证(end - start)始终是最长的,最后只需要截取就行了

例二:输入“babc”
在这里插入图片描述

刚开始left=0,right=0 程序进入第一个while循环,不满足条件,即“b” != “a”,进入第二个循环(不满足条件直接退出)

第二遍,此时left=right=1,不满足第一个循环,进入第二个,发现s[left - 1] = s[right + 1],于是继续循环。此时left=0,退出

就这样进行下去,保证(end - start)始终是最长的,最后start=0,end=2
截取为“bab”

简而言之:

整个代码的结果就是从左到右遍历,无连续相同的就以当前字符向两侧遍历看是否相等,有则从连续字符两侧遍历

posted @   soberw-  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示