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 1:

Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.

Example 2:

Input: "cbbd"
Output: "bb"

 1 class Solution {
 2     public boolean isPalindromic(String s, int begin, int end) {
 3         if (begin == end)
 4             return true;
 5         for (int i = 0; i <= (end - begin) / 2; i++) {
 6             if (s.charAt(begin + i) != s.charAt(end - i))
 7                 return false;
 8         }
 9         return true;
10     }
11 
12     public String longestPalindrome(String s) {
13         if (s.length() <= 1) return s;
14         int[] res = new int[s.length()];// 存放以当前位置结束的最长回文子串的长度
15 
16         res[0] = 1;
17         for (int i = 1; i < s.length(); i++) {
18             int begin = i - res[i - 1] - 1;//以i-1位置结尾的最长回文子串的开始位置的前一个位置
19             if (begin < 0) {
20                 /*
21                  * 查找以i结尾的最长回文子串
22                  * */
23                 for (int j = 0; j <= i; j++) {
24                     if (isPalindromic(s, j, i)) {
25                         res[i] = i - j + 1;
26                         break;
27                     }
28                 }
29             } else {
30                 if (s.charAt(begin) == s.charAt(i)) {
31                     res[i] = res[i - 1] + 2;
32                 } else {
33                     // 判断begin+1到i子串是否是回文子串
34                     for (int j = 0; j <= i; j++) {
35                         if (isPalindromic(s, j, i)) {
36                             res[i] = i - j + 1;
37                             break;
38                         }
39                     }
40                 }
41             }
42         }
43         int max = 0;
44         for (int i = 0; i < s.length(); i++) {
45             if (res[max] < res[i]) max = i;
46         }
47         return s.substring(max - res[max] + 1, max + 1);
48     }
49 }

动态规划解法:d[i][j]:表示子串(i,j)是否是回文子串

 1 class Solution {
 2     public String longestPalindrome(String s) {
 3         if (s.length() <= 0) return s;
 4         boolean[][] d = new boolean[s.length()][s.length()];
 5         int max = 0, begin = 0, end = 0;
 6         for (int i = 0; i < s.length(); i++) {
 7             d[i][i] = true;
 8         }
 9         for (int j = 1; j < s.length(); j++) {
10             for (int i = 0; i < j; i++) {
11                 if (i == j - 1) {
12                     if (s.charAt(i) == s.charAt(j)) {
13                         d[i][j] = true;
14                         if (max < j - i) {
15                             begin = i;
16                             end = j;
17                             max = j - i;
18                         }
19                     } else {
20                         d[i][j] = false;
21                     }
22                 } else {
23                     if (d[i + 1][j - 1]) {
24                         if (s.charAt(i) == s.charAt(j)) {
25                             d[i][j] = true;
26                             if (max < j - i) {
27                                 begin = i;
28                                 end = j;
29                                 max = j - i;
30                             }
31                         } else {
32                             d[i][j] = false;
33                         }
34                     } else {
35                         d[i][j] = false;
36                     }
37                 }
38             }
39         }
40         return s.substring(begin, end+1);
41     }
42 }

 第三种解法:由中间向两遍扩散查找回文串

 1 class Solution {
 2     public String longestPalindrome(String s) {
 3         if (s.length() <= 1) return s;
 4         int max = 0;
 5         int low = 0, high = 0;
 6         //计算奇数回文子串的长度
 7         for (int i = 0; i < s.length(); i++) {
 8             int begin = i, end = i;
 9             while (begin > 0 && end < s.length() - 1) {
10                 --begin;
11                 ++end;
12                 if (s.charAt(begin) == s.charAt(end)) {
13                     if (max < end - begin) {
14                         max = end - begin;
15                         low = begin;
16                         high = end;
17                     }
18                 } else {
19                     break;
20                 }
21             }
22         }
23 
24         //计算偶数回文子串的长度
25         for (int i = 0; i < s.length() - 1; i++) {
26             int begin = i, end = i + 1;
27             if (s.charAt(i) != s.charAt(i+1)) continue;
28             else {
29                 if (max < end-begin){
30                     max=end-begin;
31                     low=begin;
32                     high=end;
33                 }
34             }
35             while (begin > 0 && end < s.length() - 1) {
36                 --begin;
37                 ++end;
38                 if (s.charAt(begin) == s.charAt(end)){
39                     if (max < end-begin){
40                         max=end-begin;
41                         low= begin;
42                         high=end;
43                     }
44                 }else {
45                     break;
46                 }
47             }
48         }
49         return s.substring(low, high + 1);
50     }
51 }
原文地址:https://www.cnblogs.com/yfs123456/p/10914311.html