每日一學
阿新 • • 發佈:2022-03-29
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位置開始判斷左右是否為相同的 intleft = 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%哈。。
一次提交就過還是值得表揚的