写在前面:在LeetCode上做的题,代码基本都是我自己写的,效率有好有坏,仅供参考。
有少数几道题苦思冥想做不出来的,可能会借鉴网上大神的解法,然后再自己编写,借鉴过他人解法的题会有说明。
本人不是算法出身,语言基本靠自学,有任何错误理解或者不当举措,还请各位大侠手下留情并不吝赐教!万分感谢~
题:
5. Longest Palindromic Substring
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
Example:
Input: "babad" Output: "bab" Note: "aba" is also a valid answer.
Example:
Input: "cbbd" Output: "bb"
解题思路:
这道题想了挺久。。没有找到很好的解决方法。最开始使用两个for循环,从s.length开始慢慢缩短,然后进行判定是否是回文,但显而易见的超时了~
之后感觉怎么也跳不出双循环的黑洞。。。也是处于试探性的,既然从长到短不行,那试试从每个字符开始向前后扩散呢?
于是有了以下代码:
public class Solution { public String longestPalindrome(String s) { String ans = ""; String temp; for(int i = 0;i<s.length();i++){ temp = this.findPalindrome(s,i,i); if(temp.length()<this.findPalindrome(s,i,i+1).length()) temp = this.findPalindrome(s,i,i+1); if(ans.length()<temp.length()) ans = temp; } return ans; } public String findPalindrome(String s,int start,int end){ while(start>=0&&end<s.length()&&s.charAt(start)==s.charAt(end)){ start--; end++; } return s.substring(start+1,end); } }
这是对每个字符调用一次findPalindrome方法,这个方法就是从当前字符(或者是当前以及紧接着的下一个两个字符,因为aba和abba都是回文)开始向前向后同时对比,看看最长回文能延伸到哪,最后返回当前符合要求的回文。
每个字符需要经历两次调用,一次是单个字符,一次是当前和接下来的一个字符一起。在for循环中记录最长的回文,最后完成查找。LeetCode用时53ms,比最开始的两个for循环快了不少。
但运行结果显示我的成绩是40.89%,于是我看了下大神的杰作:
class Solution { private int max_length; private int start; public String longestPalindrome(String input) { if(input == null || input.length() < 2) return input; char[] str = input.toCharArray(); for(int i = 0; i < str.length;) { i = extendPalin(str, i); } return new String(str, start, max_length); } private int extendPalin(char[] str, int cursor) { int i = cursor, j = cursor; // For repetition, just skip and put in the middle of palindrome while(j < str.length - 1 && str[j] == str[j + 1]) j++; int skip = j + 1; while(i >= 0 && j < str.length && str[i] == str[j]) { i--; j++; } i++; j--; if(max_length < j - i + 1) { start = i; max_length = j - i + 1; } // return the index after skipping the duplicated entries to continue return skip; } }
这是LeetCode上一个大神的答案,用时9ms。。。。。。简直粗暴,分析了下原理,大致上差不多,关键多了个skip变量。这个变量的作用是将一连串重复出现的字符跳过,举例说明:
例如传入的变量是“abcdddddcbefghj”按照我们的解法,是循环15次,对每个字符进行左右扩展。而加入了skip变量之后,在循环到第一个d字符时,会进行跳跃,使下一次循环直接从下标为8的c字符开始。这样做是因为,在一长串相同字符里,最长回文只可能出现在其中间位置,因此,再对其他位置的“d”进行判定的工作是多余的。
浙公网安备 33010602011771号