每日一学

1.最长的回文串

做法:

中心扩散法,依次遍历字符串的每一个字符,从当前字符往两边进行扩散,查找最长的回文子串

 

 

但是显而易见,假如该字符串的回文子串是偶数的呢?那么这种做法就会摆的一败涂地

所以当进行运行的时候我们要判断一下,其相邻的位置是否存在相同的字符,如果存在相同的字符就可以跳过

s.substring(start, start + maxLen);作用就是截取指定范围的数据

这是我第一次写的时候的代码

复制代码
package two24;

public class Solution5 {
    public String longestPalindrome(String s) {
//        现在此代码已经实现了奇数回文子串的判断,但是如果为偶数依旧判断不了
//      那这两个数据来实现字符串的返回,其中
        int start = 0, maxLen = 0;

//        先排除特殊情况
        if (s == null||s.length() < 1) {
            return "";
        }
//        中间扩散法判断
        for (int i = 0; i < s.length(); i++) {
//            从i位置开始判断左右是否为相同的
            int left = i;
            int right = i;
            if(right==i&&right<s.length()-1){
                if(s.charAt(right)==s.charAt(right+1))
                {
                    right++;
                }
            }
            while(left>0&&right<s.length()-1){

                if(s.charAt(left-1)==s.charAt(right+1)){
                    --left;
                    ++right;
                }else{
                    break;
                }
            }
            if(right-left+1>maxLen){
                start = left;
                maxLen = right-left+1;
            }
        }

        return s.substring(start,start+maxLen);
    }
}
复制代码

这是在网上看到的

复制代码
package two24;

import java.util.ArrayList;
import java.util.Collection;

public class  test{
    String longestPalindrome(String s) {
        //边界条件判断
        if (s.length() < 2)
            return s;
        //start表示最长回文串开始的位置,
        //maxLen表示最长回文串的长度
        int start = 0, maxLen = 0;
        int length = s.length();
        for (int i = 0; i < length; ) {
            //如果剩余子串长度小于目前查找到的最长回文子串的长度,直接终止循环
            // (因为即使他是回文子串,也不是最长的,所以直接终止循环,不再判断)
            if (length - i <= maxLen / 2)
                break;
            int left = i, right = i;
            while (right < length - 1 && s.charAt(right + 1) == s.charAt(right))
                ++right; //过滤掉重复的
            //下次在判断的时候从重复的下一个字符开始判断
            i = right + 1;
            //然后往两边判断,找出回文子串的长度
            while (right < length - 1 && left > 0 && s.charAt(right + 1) == s.charAt(left - 1)) {
                ++right;
                --left;
            }
            //保留最长的
            if (right - left + 1 > maxLen) {
                start = left;
                maxLen = right - left + 1;
            }
        }
        //截取回文子串
        return s.substring(start, start + maxLen);
    }


}
复制代码

说起来也离谱,明明感觉一样了,却依旧错了

i = right + 1;

上面这个好像是唯一的不同之处。。

但是随着我的一步步的深究我发现还存在一处不同的地方,那就是那个判断相邻的位置是否存在相同的点的方法,不应该使用if,我当时就感觉不对劲,如果使用while那不就会出现三个或者多个同时在一起的情况,那就会很难处理,但是使用while就不需要担心这一种情况。太牛了

复制代码
package two24;

public class Solution5 {
    public String longestPalindrome(String s) {
//        现在此代码已经实现了奇数回文子串的判断,但是如果为偶数依旧判断不了
//      那这两个数据来实现字符串的返回,其中
        int start = 0, maxLen = 0;

//        先排除特殊情况
        if (s.length()  < 2) {
            return s;
        }
//        中间扩散法判断
        for (int i = 0; i < s.length(); ) {
//            从i位置开始判断左右是否为相同的
            if (s.length() - i <= maxLen / 2)
                break;
            int left = i;
            int right = i;
//            差别是if改成while,确实牛批,这样就不需要判断左右是否都相同的情况了
            while(s.charAt(right + 1) == s.charAt(right)&&right<s.length()-1){
                right++;
            }
            i = right + 1;
            while(left>0&&right<s.length()-1){

                if(s.charAt(left-1)==s.charAt(right+1)){
                    --left;
                    ++right;
                }
            }
            if(right-left+1>maxLen){
                start = left;
                maxLen = right-left+1;
            }
        }

        return s.substring(start,start+maxLen);
    }
}
复制代码

上面那个是改进之后的代码,但是一直报超限错误,烦了半天,直到最后debug和源码比较才发现,应该把那个判断是否相等的放在前面

就成了这一个代码

复制代码
package two24;

public class Solution5 {
    public String longestPalindrome(String s) {
//        现在此代码已经实现了奇数回文子串的判断,但是如果为偶数依旧判断不了
//      那这两个数据来实现字符串的返回,其中
        int start = 0, maxLen = 0;

//        先排除特殊情况
        if (s.length()  < 2) {
            return s;
        }
//        中间扩散法判断
        for (int i = 0; i < s.length(); ) {
//            从i位置开始判断左右是否为相同的
            if (s.length() - i <= maxLen / 2)
                break;
            int left = i;
            int right = i;
//            差别是if改成while,确实牛批,这样就不需要判断左右是否都相同的情况了
            while(right<s.length()-1&&s.charAt(right + 1) == s.charAt(right)){
                right++;
            }
            i = right + 1;
            while(left>0&&right<s.length()-1){

                if(s.charAt(left-1)==s.charAt(right+1)){
                    --left;
                    ++right;
                }
            }
            if(right-left+1>maxLen){
                start = left;
                maxLen = right-left+1;
            }
        }

        return s.substring(start,start+maxLen);
    }
}
复制代码

太tmd细了

但是后来运行测试代码的时候又报错了。。

复制代码
package two24;

public class Solution5 {
    public String longestPalindrome(String s) {
//        现在此代码已经实现了奇数回文子串的判断,但是如果为偶数依旧判断不了
//      那这两个数据来实现字符串的返回,其中
        int start = 0, maxLen = 0;

//        先排除特殊情况
        if (s.length()  < 2) {
            return s;
        }
//        中间扩散法判断
        for (int i = 0; i < s.length();) {
//            从i位置开始判断左右是否为相同的
            if (s.length() - i <= maxLen / 2)
                break;
            int left = i;
            int right = i;
//            差别是if改成while,确实牛批,这样就不需要判断左右是否都相同的情况了
            while(right<s.length()-1&&s.charAt(right + 1) == s.charAt(right)){
                right++;
            }
            i = right + 1;
            while(left>0&&right<s.length()-1&&s.charAt(left-1)==s.charAt(right+1)){
                    --left;
                    ++right;
            }
            if(right-left+1>maxLen){
                start = left;
                maxLen = right-left+1;
            }
        }

        return s.substring(start,start+maxLen);
    }
}
复制代码

处理完,发现原因是那个判断两边的数是否相同的地方出现了错误,就卡在那里不动了

每一步都有他自己的用处,切莫粗心大意

 

 一次过,超过100%的人,还可以哈哈

复制代码
package two24;

public class Solution88 {
    public int [] merge(int[] nums1, int m, int[] nums2, int n) {
//极其牛批
        int[] num3 = new int[m+n];
        int j = 0;
        int i;
        for( i = 0; i < m; i++)
        {

            for( ; j < n; j++){

                if(nums1[i]<nums2[j])
                {
                    num3[j+i] = nums1[i];
                    break;
                }
                else{
                    num3[j+i] = nums2[j];
                    continue;
                }
            }
            if(j == n){
                num3[j+i]=nums1[i];
            }
        }
        if(i==m)
        {
            for( ; j < n; j++){
                num3[j+i] = nums2[j];
                continue;
            }
        }

        for(i = 0;i<nums1.length;i++)
        {
            nums1[i] = num3[i];
        }

        return nums1;
    }
}
复制代码

这种简单的题好像一般都是超过100%哈。。

一次提交就过还是值得表扬的

 

posted @   湖南陈冠希  阅读(110)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
点击右上角即可分享
微信分享提示