LeetCode:最长回文子串

刷题神器:LeetCode官方网站

一、题目还原

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

二、解题思路

1)Solution1 暴力解法
① 双层循环,逐一比对是否为回文子串。记录最长子串

2)Solution2 中心扩散法
① EdgeCase:判空返回"",只有一个字符返回该字符
② 以任意一点 j 为回文子串的中心点向两边扩散,向左left --,向右right ++
③ 根据奇偶判定,如果是奇数,left = j - 1; right = j + 1,偶数则left = j , right = j + 1
④ 根据是否越界,以及left和right所对应的值是否相等条件返回左右下标,截取子串
⑤ 如果遍历到最后发现得不到超过一个字符的回文子串,则返回第一个字符

三、代码展示

① main函数

public static void main(String[] args) {
    String s = "cyyoacmjwjubfkzrrbvquqkwhsxvmytmjvbborrtoiyotobzjmohpadfrvmxuagbdczsjuekjrmcwyaovpiogspbslcppxojgbfxhtsxmecgqjfuvahzpgprscjwwutwoiksegfreortttdotgxbfkisyakejihfjnrdngkwjxeituomuhmeiesctywhryqtjimwjadhhymydlsmcpycfdzrjhstxddvoqprrjufvihjcsoseltpyuaywgiocfodtylluuikkqkbrdxgjhrqiselmwnpdzdmpsvbfimnoulayqgdiavdgeiilayrafxlgxxtoqskmtixhbyjikfmsmxwribfzeffccczwdwukubopsoxliagenzwkbiveiajfirzvngverrbcwqmryvckvhpiioccmaqoxgmbwenyeyhzhliusupmrgmrcvwmdnniipvztmtklihobbekkgeopgwipihadswbqhzyxqsdgekazdtnamwzbitwfwezhhqznipalmomanbyezapgpxtjhudlcsfqondoiojkqadacnhcgwkhaxmttfebqelkjfigglxjfqegxpcawhpihrxydprdgavxjygfhgpcylpvsfcizkfbqzdnmxdgsjcekvrhesykldgptbeasktkasyuevtxrcrxmiylrlclocldmiwhuizhuaiophykxskufgjbmcmzpogpmyerzovzhqusxzrjcwgsdpcienkizutedcwrmowwolekockvyukyvmeidhjvbkoortjbemevrsquwnjoaikhbkycvvcscyamffbjyvkqkyeavtlkxyrrnsmqohyyqxzgtjdavgwpsgpjhqzttukynonbnnkuqfxgaatpilrrxhcqhfyyextrvqzktcrtrsbimuokxqtsbfkrgoiznhiysfhzspkpvrhtewthpbafmzgchqpgfsuiddjkhnwchpleibavgmuivfiorpteflholmnxdwewj";
    //String s = "ac";
    System.out.println("longestPalindrome最长回子串 === "+longestPalindrome(s));
    System.out.println("longestPalindrome2最长回子串 === "+longestPalindrome2(s));
}

② longestPalindrome方法函数

//暴力法,超时!
public static  String longestPalindrome(String s) {
    String maxStr = "";
    int maxLength  = 0;
    if(null != s && !"".equals(s)){
        for(int i = 0; i<=s.length() ; i++){
            for(int  j = i; j <= s.length() ; j++){
                String s1 = s.substring(i,j);
                if(s1.contentEquals(new StringBuffer(s1).reverse())){
                    if(maxLength < s1.length()){
                       maxLength = s1.length();
                       maxStr = s1;
                    }
                }
            }
        }
    }
    return maxStr;
}

控制台输出:

longestPalindrome最长回子串 === xrcrx

Process finished with exit code 0

虽然该方法得到结果正确,但是在提交后直接超出了时间限制
Q5超时

③ longestPalindrome2和expand方法函数

//中心扩散法
public static String longestPalindrome2(String s) {
    //判空
    if(null == s || s.isEmpty()){
        return "";
    }

    //只有一个数字的时候
    if(s.length() == 1){
        return s;
    }
    int maxLength = 0;
    String maxStr = "";
    String[] arr = s.split("");
    int j = 0;

    while(j<arr.length){
        //奇数情况
        int a[] = expand(arr,j-1,j+1);
        //偶数情况
        int b[] = expand(arr,j,j+1);
        if(a[1] - a[0] > b[1] - b[0] && a[1] - a[0] > maxLength){
            maxLength = a[1] - a[0];
            maxStr = s.substring(a[0],a[1]+1);
        }else if(b[1] - b [0] > maxLength){
            maxLength = b[1] - b[0];
            maxStr = s.substring(b[0],b[1]+1);
        }
        j++;
    }

    //不是回文字符,返回第一个字符
    if(maxLength == 0){
        maxStr = arr[0];
    }

    return  maxStr;
}
//向两边扩展判断是否为回文字符,返回数字a[0]为左下标,a[1]为右下标
public static int[] expand(String[] arr, int left, int right){
    int a[] ={0,0};
    if(left < 0){
        a[0] = 0;
        a[1] = 0;
       return a;
    }else if(right >= arr.length){
        a[0] = arr.length - 1;
        a[1] = arr.length - 1;
        return a;
    }

    while(left > -1 && right < arr.length && arr[left].equals(arr[right])){
        left -- ;
        right ++;
    }

    a[0] = left+1;
    a[1] = right-1;
    return a;
}

控制台输出:

longestPalindrome2最长回子串 === xrcrx

Process finished with exit code 0
四、自我总结

这是LeecCode题库的第五题,难度为中等,博主今日可栽跟头了,一开始就想用暴力解法两层循环把所有情况都遍历一遍进行比对,这样的做法虽然稳妥,但是在执行效率上非常的低,双层循环中套了一个比较回文数,使用了reverse()方法,相当于三层循环,时间复杂度为O(n3),第一次提交也就是失败了。
Q5提交记录
继续之前的优化思路,为了减少循环层数,博主最先想到的是中心扩散法,一个字符串进行遍历,在进行中心扩散,其最坏时间复杂度才为O(n2),相比暴力解法优化了许多,但是未考虑“”、单字符以及没有超过单字符的回文子串这些EdgeCase,在提交n次失败后才顺利提交成功,但从提交的成绩来看还是有待提升的,看到评论区大神大多说用动态规划的思路,博主后期也会研究研究,继续提升自我!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,有三种方法可以解决LeetCode上的最长回文子串问题。 方法一是使用扩展中心法优化,即从左向右遍历字符串,找到连续相同字符组成的子串作为扩展中心,然后从该中心向左右扩展,找到最长的回文子串。这个方法的时间复杂度为O(n²)。\[1\] 方法二是直接循环字符串,判断子串是否是回文子串,然后得到最长回文子串。这个方法的时间复杂度为O(n³),效率较低。\[2\] 方法三是双层for循环遍历所有子串可能,然后再对比是否反向和正向是一样的。这个方法的时间复杂度也为O(n³),效率较低。\[3\] 综上所述,方法一是解决LeetCode最长回文子串问题的最优解法。 #### 引用[.reference_title] - *1* [LeetCode_5_最长回文子串](https://blog.csdn.net/qq_38975553/article/details/109222153)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Leetcode-最长回文子串](https://blog.csdn.net/duffon_ze/article/details/86691293)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [LeetCode 第5题:最长回文子串(Python3解法)](https://blog.csdn.net/weixin_43490422/article/details/126479629)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值