寻找最大回文字符子串

 
  

输入:“babad”

输出:“bab”或者“aba”

一,暴力解法,但是空间复杂度为常数级

class Solution {
    public String longestPalindrome(String s) {
        int start = 0, end = 0;
		for(int i = 0; i < s.length(); i++){
			int len1 = expandAroundCenter(s, i, i);
			int len2 = expandAroundCenter(s, i, i+1);
			int len = Math.max(len1, len2);
			if(len > end - start){
				start = i - (len - 1)/2;
				end = i + len/2;
			}
		}
		
		return s.substring(start, end+1);
	}
   
    public static int expandAroundCenter(String s, int start, int end){
		int L = start, R = end;
		while(L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)){
			L--;
			R++;
		}
		return R - L - 1;
	}
}

思路:对于n长的字符串他可以分割的点为2n - 1。因为如果是奇数位子串,则它的分割点为中间的字符,如果是偶数位子串,则
它的分割点为中间点。所以expandAroundCenter(s, i, i)就是奇数位子串的测试,从中心点逐渐向两边延伸

而expandAroundCenter(s, i, i+1)就是偶数位子串的测试。

二,动态规划解决问题

string longestPalindromeDP(string s) {
  int n = s.length();
  int longestBegin = 0;
  int maxLen = 1;
  bool table[1000][1000] = {false};
  for (int i = 0; i < n; i++) {
    table[i][i] = true;
  }
  for (int i = 0; i < n-1; i++) {
    if (s[i] == s[i+1]) {
      table[i][i+1] = true;
      longestBegin = i;
      maxLen = 2;
    }
  }
  for (int len = 3; len <= n; len++) {
    for (int i = 0; i < n-len+1; i++) {
      int j = i+len-1;
      if (s[i] == s[j] && table[i+1][j-1]) {
        table[i][j] = true;
        longestBegin = i;
        maxLen = len;
      }
    }
  }
  return s.substr(longestBegin, maxLen+longestBegin);
}

思路:使用P(i, j)表示从i到j的字符串是否为回文串,如果是则P(i, j) = 1, 否则为P(i, j) = 0。

基本条件P(i, i) = 1            P(i, i+1) = (s(i) == s(i+1))

因此得出推断 P(i, j) = (P(i+1, j - 1) and s(i) == s(j))
以上是最大只能为两个长度,所以我们应该考虑大于2的情况, 从3直至子串的长度,考虑的起始点为字符串的起始点,依次向后类推,判断是否符合回文串。

你可能感兴趣的:(刷leetcode)