题目中文:求最长回文子串
题目难度:Medium
题目内容:
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
翻译:
给定一个字符串s,找出s中最长的回文子串。你可以假设s的最大长度是1000。
什么叫回文子串?
就是字符串中,满足能正读反读都一样的子串,就是回文子串。如下所示
Input: "babad" Output: "bab" Note: "aba" is also a valid answer.
我的思路:既然是特殊的子串那么,首先得得到每一个子串。然后用一个方法判定是否是回文,是的话就与答案长度做比较,更长则更新答案。
MyCode:
1 public String longestPalindrome(String s) { 2 int n = s.length(); 3 String ans = ""; 4 Set<String> set = new HashSet<String>(); 5 for (int i = 0; i < n; i++) { 6 for (int j = i + 1; j <= n; j++) { 7 set.add(s.substring(i, j)); 8 } 9 } 10 for (String m : set) { 11 if (isPalindromic(m)) { 12 ans = m.length()>ans.length()?m:ans; 13 } 14 } 15 return ans; 16 } 17 18 public boolean isPalindromic (String m) { 19 String reverse = new StringBuffer(m).reverse().toString(); 20 return m.equals(reverse) ? true : false; 21 }
我的算法复杂度:O(N2)
结果不出意料:Time Limit Exceeded
编程过程中出现的问题:
1、因为最近在用python参加比赛,所以总是忘记定义变量类型。。。
2、一开始对回文子串理解错误,导致编程出错,所以啊,还是先看清题,理解题目意思再说;
3、String之间的比较一个手抖就直接用了“==”,哎 equals() 啊,我怎么总是对不起你。
然后傻呵呵地看答案去了…………
答案:
1 class Solution { 2 String ans = ""; 3 public String longestPalindrome(String s) { 4 for (int i = 0;i < s.length(); i++) { 5 extendVerify(s,i,i); 6 extendVerify(s,i,i+1); 7 } 8 return ans; 9 } 10 public void extendVerify(String s, int j, int k) { 11 while (j >= 0 && k < s.length() && s.charAt(j) == s.charAt(k)) { 12 j--; 13 k++; 14 } 15 String subString = s.substring(j+1,k); 16 ans = subString.length()>ans.length()?subString:ans; 17 } 18 }
答案算法复杂度:O(N)~ O(N2)
答案思路:分两部分,主方法对每个字符进行遍历,然后调用子方法由此字符出发向两边进行扩展,同时用两“指针”对左右的扩展字符进行比较,
调用两次子方法分别验证了以此字符为中心的左右的单数和双数的回文。
此代码还能优化:
1、主方法对s进行判断,如果长度小于2,即可直接返回s;
2、主方法的循环结束条件可以设置成 s.length - 1 , 因为最后一个没法往外扩展(但是0不能省,因为判断偶数扩展的时候必须是从(0,1)这两个开始);
3、子方法最后的更新其实只需要判断 j+1 到 k-1 的长度与 一个maxLen 的比较,然后再将 起始位置 j + 1,与长度 maxLen = k - j - 1 进行保存,就可以完成更新。