LeetCode 5. Longest Palindromic Substring

原题链接在这里:https://leetcode.com/problems/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"

题解:

以字符串的每一个char 为中心开始向左右延展,直到不是回文为止,若新的substring 比原来的res长,就更新res.

Note: 子字符串的中心可以是一个字符,整个字符串有奇数个字符;也可以是两个字符中间的空隙,整个字符串有偶数个字符。

Note: longest辅助函数在左右延展时,跳出while loop时,i 和 j 指向的要么是out of index bound, 要么指向的字符已经不想等了。所以最后返回的最常字符串应该是substring(i+1,j)这一段, j 指向的 字符并没有包括在最后结果中。

Time Complexity: O(n^2). n = s.length(). Space: O(n), res的长度。

AC Java: 

 1 public class Solution {
 2     public String longestPalindrome(String s) {
 3         if(s == null || s.length() == 0){
 4             return s;
 5         }
 6         String res = "";
 7         for(int i = 0; i<s.length(); i++){
 8             //string with odd # of characters
 9             String longestOddSubstring = findLongest(s, i, i);
10             if(longestOddSubstring.length() > res.length()){
11                 res = longestOddSubstring;
12             }
13             //string with even # of characters
14             String longestEvenSubstring = findLongest(s, i, i+1);
15             if(longestEvenSubstring.length() > res.length()){
16                 res = longestEvenSubstring;
17             }
18         }
19         return res;
20     }
21     
22     //find the longest palindromic substring
23     private String findLongest(String s, int i, int j){
24         while(i>=0 && j<s.length() && s.charAt(i) == s.charAt(j)){
25             i--;
26             j++;
27         }
28         return s.substring(i+1,j);
29     }
30 }

AC Python:

 1 class Solution:
 2     def longestPalindrome(self, s: str) -> str:
 3         if not s:
 4             return s
 5         
 6         res = ""
 7         for i in range(len(s)):
 8             oddCan = self.findLongest(s, i, i)
 9             if len(oddCan) > len(res):
10                 res = oddCan
11             evenCan = self.findLongest(s, i, i + 1)
12             if len(evenCan) > len(res):
13                 res = evenCan
14         return res
15         
16     def findLongest(self, s, l, r):
17         while l >= 0 and r < len(s) and s[l] == s[r]:
18             l -= 1
19             r += 1
20         return s[l + 1:r]

可以用index取得结果来节省空间. 当前index 为i向两边延展后取得的最长palindrome substring的长度len.

最长palindrome substring的左侧index就是i-(len-1)/2, 右侧index就是i+len/2. 

Time Complexity: O(n^2). n = s.length().

Space: O(1).

AC Java:

 1 class Solution {
 2     public String longestPalindrome(String s) {
 3         if(s == null || s.length() == 0){
 4             return s;
 5         }
 6         
 7         int l = 0;
 8         int r = 0;
 9         for(int i = 0; i<s.length(); i++){
10             int longestOddSubstringLen = findLongest(s, i, i);
11             int longestEvenSubstringLen = findLongest(s, i, i+1);
12             int longestSubstringLen = Math.max(longestOddSubstringLen, longestEvenSubstringLen);
13             if(longestSubstringLen > r-l+1){
14                 l = i-(longestSubstringLen-1)/2;
15                 r = i+longestSubstringLen/2;
16             }
17         }
18         return s.substring(l, r+1);
19     }
20     
21     private int findLongest(String s, int i, int j){
22         while(i>=0 && j<s.length() && s.charAt(i)==s.charAt(j)){
23             i--;
24             j++;
25         }
26         return j-i-1;
27     }
28 }

AC Python:

 1 class Solution:
 2     def longestPalindrome(self, s: str) -> str:
 3         if not s:
 4             return s
 5         l, r = 0, 0
 6         for i in range(len(s)):
 7             oddCan = self.findLongest(s, i, i)
 8             evenCan = self.findLongest(s, i, i + 1)
 9             maxCan = max(oddCan, evenCan)
10             if maxCan > r - l + 1:
11                 l = i - (maxCan - 1) // 2
12                 r = i + maxCan // 2
13         return s[l : r + 1]
14     
15     def findLongest(self, s, l, r):
16         while l >= 0 and r < len(s) and s[l] == s[r]:
17             l-=1
18             r+=1
19         return r - l -1

DP 方法. dp[i][j]记录s.substring(i, j+1)是否为Palindromic.

dp[i][j] = (s.charAt(i) == s.charAt(j) && (j-i<2 || dp[i+1][j-1]).

Time Complexity: O(n^2). Space: O(n^2).

 1 public class Solution {
 2     public String longestPalindrome(String s) {
 3         if(s == null || s.length() == 0){
 4             return s;
 5         }
 6         
 7         String res = "";
 8         int len = s.length();
 9         boolean [][] dp = new boolean[len][len];
10         for(int i = len-1; i>=0; i--){
11             for(int j = i; j<len; j++){
12                 //Need to check j-i < 2 first 
13                 //or IndexOutOfBondException
14                 if(s.charAt(i) == s.charAt(j) && (j-i<2 || dp[i+1][j-1])){ 
15                     dp[i][j] = true;
16                     if(j-i+1 > res.length()){
17                         res = s.substring(i, j+1);
18                     }
19                 }
20             }
21         }
22         return res;
23     }
24 }

AC Python:

 1 class Solution:
 2     def longestPalindrome(self, s: str) -> str:
 3         if not s:
 4             return s
 5         n = len(s)
 6         dp = [[False for _ in range(n)] for _ in range(n)]
 7         res = ""
 8         for i in range(n - 1, -1, -1):
 9             for j in range(i, n):
10                 if s[i] == s[j] and (j - i < 2 or dp[i + 1][j - 1]):
11                     dp[i][j] = True
12                     if len(res) < j - i + 1:
13                         res = s[i:j + 1]
14         return res     

类似Palindromic SubstringsLongest Palindromic Subsequence.

posted @ 2015-10-29 22:20  Dylan_Java_NYC  阅读(385)  评论(0编辑  收藏  举报