欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

每天一道算法题系列五之最长回文子串

程序员文章站 2022-05-10 11:31:00
每天一道算法题系列:来源:力扣(LeetCode)本题链接:https://leetcode-cn.com/problems/longest-palindromic-substring/来源是力扣,大家喜欢可以去力扣中文网做相应的其他的题,某浏览器直接搜力扣即可。本题难度是中等给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。示例 1:输入: “babad”输出: “bab”注意: “aba” 也是一个有效答案。示例 2:输入: “cbbd”输...

每天一道算法题系列:
来源:力扣(LeetCode)
本题链接:https://leetcode-cn.com/problems/longest-palindromic-substring/
来源是力扣,大家喜欢可以去力扣中文网做相应的其他的题,某浏览器直接搜力扣即可。
本题难度是中等

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”


/**
 * 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
 * <p>
 * 示例 1:
 * <p>
 * 输入: "babad"
 * 输出: "bab"
 * 注意: "aba" 也是一个有效答案。
 * 示例 2:
 * <p>
 * 输入: "cbbd"
 * 输出: "bb"
 */
public class LongestPalindrome {
/*
这种做法是暴力的方式,暴力就是一个for循环不行,那就来两个。
然后从第一个循环的第一位分别和第二个循环的最后一位到第一位的形式
值得注意的一点,第二个for循环必须是j>0,不然如果是bb的话,他的回文就只有b
*/
    public static String longestPalindrome1(String s) {
        int maxLen = 1;
        int begin = 0;
        int end = 0;
        for (int i = 0; i < s.length() - 1; i++) {
            for (int j = s.length() - 1; j > 0; j--) {
                /*
                j-i+1是为了判断取最长的回文字段,如果不加这个判断的话,就会有很多的回文段
                */
                if ((j - i + 1) > maxLen && test(s, i, j)) {
                    begin = i;
                    end = j;
                    //这里不断的更新maxLen的值 去上面做比较
                    maxLen = j - i + 1;
                }
            }
        }
        return s.substring(begin, end + 1);
    }

    /*
     这个方法是为了判断是否回文的方法
     */
    public static boolean test(String s, int begin, int end) {
        /*
        这里判断begin小于end,是因为防止都对比到中间了 还继续进行判断
        主要是和后面的begin++  和 end-- 相呼应
         */
        while (begin <= end) {

            if (s.charAt(begin) != s.charAt(end)) {
                return false;
            }
            begin++;
            end--;

        }
        return true;
    }

    public static void main(String[] args) {
        System.out.println(longestPalindrome1("s1a2d2a1s"));
    }
}
 /*
    第二种解法是从中间往两边减的方式  比如rqwerewqs这种
    从r开始往后面r->q->w->e->r->e->w->q->s这样,如果是q去往r和w去判断
    是w就判断q->r 和 e->r这样的方式,后面依次类推
     */
    public static String longestPalindrome1(String s) {
       
        int maxLen = 0;
        int start = 0 ;
        int end = 0 ;
        for (int i = 0; i < s.length(); i++) {
            int test1 = test(s, i, i);//这个是面对s的值是奇数的情况
            int test2 = test(s, i, i + 1);//这个是面对s的值是偶数的情况
            maxLen = test1 > test2 ? test1 : test2 ;

            if(maxLen > end - start){
                /*
                这里为什么取的是(maxLen-1) / 2,其实也可以看
                比如rqwerewqs这种,返回的maxLen是等于7的然后算的其实位置其实就是1

                 */
                start = i - (maxLen-1) / 2;
                end = i + maxLen / 2;
            }
        }

        return s.substring(start, end + 1);
    }

    public static int test(String s, int begin, int end) {
        while (begin >= 0 && end < s.length() && s.charAt(begin) == s.charAt(end)) {
            begin--;
            end++;
        }
        /*这里返回的值是right - left - 1
        比如rqwerewqs这种,最后判断得到的是qwerewq
        得到的begin应该是第一个q ,位置是1,然后end是第二个q 位置是7
        但是因为会多经历一次while里面的循环 最后得到的值begin=0;end=8
        然后两个q中间其实只有7个数,所以应该是end-begin等于8  还需要减1
         */
        return end - begin - 1;
    }

上一篇内容:每天一道算法题系列四之无重复字符的最长子串
请继续关注我,如果后面不忙了,会写一系列关于的设计模式的文章。
如果本篇内容有问题,请第一时间联系我,我会第一时间修改。
谢谢大家。

本文地址:https://blog.csdn.net/qq_38091343/article/details/109597523