Longest Palindromic Substring Leetcode
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"
一开始的解法不能通过全部的test case,最后一个会超时,其他都可以。思路就是遇到一个值,看看hashmap里面有没有相同的值,如果相同,检查两个之间是不是palidrome。其实时间复杂度也没那么高,放上来做个纪念吧。。。
public class Solution { public String longestPalindrome(String s) { if (s == null || s.length() == 0) { return s; } char[] c = s.toCharArray(); Map<Character, List<Integer>> hm = new HashMap<>(); int start = 0; int end = 0; for (int i = 0; i < c.length; i++) { if (hm.containsKey(c[i])) { for (int index : hm.get(c[i])) { if (isPalindrome(c, index, i) && i - index >= end - start) { start = index; end = i; break; } } } else { hm.put(c[i], new ArrayList<>()); } hm.get(c[i]).add(i); } return new String(c, start, end - start + 1); } public boolean isPalindrome(char[] c, int a, int b) { while (a < b) { if (c[a] != c[b]) { return false; } a++; b--; } return true; } }
用扩展palindrome的方法来写还挺好的。需要注意的是if的判断条件,以为已经加过减过了,所以判断和赋值的的时候要把这个影响算上。
public class Solution { int start = 0; int end = 0; public String longestPalindrome(String s) { if (s == null || s.length() < 2) { return s; } char[] c = s.toCharArray(); for (int i = 0; i < c.length; i++) { extendPalindrome(c, i, i); extendPalindrome(c, i, i + 1); } return new String(c, start, end - start + 1); } public void extendPalindrome(char[] c, int a, int b) { while (a >= 0 && b < c.length && c[a] == c[b]) { a--; b++; } if (b - 1 - a - 1 >= end - start) { start = a + 1; end = b - 1; } } }
如果嫌弃全局变量的话还可以写成一个函数。
另一种解法:
public class Solution { public String longestPalindrome(String s) { if (s == null || s.length() < 2) { return s; } int start = 0; int maxLen = 0; char[] c = s.toCharArray(); for (int i = 0; i < c.length;) { if (c.length - i < maxLen / 2) { break; //The remain characters can not form longer palindrome. } int j = i; int k = i; while (k < c.length - 1 && c[k] == c[k + 1]) { k++; //Skip duplicates. } i = k + 1; while (j >= 0 && k < c.length && c[k] == c[j]) { k++; j--; } int len = k - 1 - j; if (len > maxLen) { start = j + 1; maxLen = len; } } return new String(c, start, maxLen); } }
这种方法通过跳过相同的字符的方法避免了奇偶的区别。i从k+1再开始,避免了一个字符多次判断。