每日一学
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%哈。。
一次提交就过还是值得表扬的
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决