1. 程式人生 > 其它 >每日一學

每日一學

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%哈。。

一次提交就過還是值得表揚的