回文

普通回文判断

  普通的回文判断还是比较简单的。有如下几种选择:
  1. 将字符串翻转,与原字符串依次比较;
  2. 头尾比较,一直比较到string.length()/2的位置。

最长回文字符串判断

  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:
Input: “babad”
Output: “bab”

Note: “aba” is also a valid answer.

Example:
Input: “cbbd”
Output: “bb”

虽然题目依旧叫做回文的“判断”。但是如果这里依旧循着判断的思路(即给定一个长度的字符串,判断它是不是回文)进行的话,比较难想出低复杂度的方案。因此,这里选择自行“生成”回文而不是判断的方案会更加便利。当然,“判断”方案也是有的。

自行生成的方案:
以每一个或每两个字符作为回文的中心,生成回文

private int lo, maxLen;

public String longestPalindrome(String s) {
    int len = s.length();
    if (len < 2)
        return s;

    for (int i = 0; i < len-1; i++) {
        extendPalindrome(s, i, i);  //assume odd length, try to extend Palindrome as possible
        extendPalindrome(s, i, i+1); //assume even length.
    }
    return s.substring(lo, lo + maxLen);
}

private void extendPalindrome(String s, int j, int k) {
    while (j >= 0 && k < s.length() && s.charAt(j) == s.charAt(k)) { 
    // 从里往外 一点点 构建回文
        j--;
        k++;
    }
    if (maxLen < k - j - 1) {
        lo = j + 1;
        maxLen = k - j - 1;
    }
}

依旧采用判断的dp方案

public String longestPalindrome(String s) {
  int n = s.length();
  String res = null;

  boolean[][] dp = new boolean[n][n];//初始化 默认值 为false

  //************************************************
  //*****非递归dp,外层从后往前,内层从i开始 反向*********
  //************************************************
  for (int i = n - 1; i >= 0; i--) {
    for (int j = i; j < n; j++) {
    //也算是从小范围到大范围一点点构建dp数组,判断时从外往里判断
      dp[i][j] = s.charAt(i) == s.charAt(j) && (j - i < 3 || dp[i + 1][j - 1]);

      if (dp[i][j] && (res == null || j - i + 1 > res.length())) {
        res = s.substring(i, j + 1);
      }
    }
  }

  return res;
}

最长回文序列判断

  LeetCode 516. Longest Palindromic Subsequence

Given a string s, find the longest palindromic subsequence’s length in s. You may assume that the maximum length of s is 1000.

Example 1:
Input:
“bbbab”
Output:
4
One possible longest palindromic subsequence is “bbbb”.

Example 2:
Input:
“cbbd”
Output:
2
One possible longest palindromic subsequence is “bb”.

  乍一看比上面一题难,因为是从序列中挑选任意数量的字符(不改变相对顺序)成为回文序列。然而,仔细分析一下,会发现其满足DP的所有要素:
  1. 子问题分解
  从序号ij 内含有的最长回文子序列等价于[i+1,j] [i,j-1] [i+1,j-1] 三个相关的子问题,且都和母问题是一种性质的问题。
  2. 子问题独立,存在最优子结构
  上面三个问题都是独立的,并且有一个(或两个)是最优的。
  3. 存在边界
  当i > j 时,最长回文子序列长度为 0,当i = j 时,最长回文子序列长度为 1。
  4. 备忘录
  用int dp[i][j] 可以表示范围ij 内含有的最长回文子序列的长度。

代码如下:

public class Solution {
    public int longestPalindromeSubseq(String s) {
        int[][] dp = new int[s.length()][s.length()];

        //************************************************
        //*****非递归dp,外层从后往前,内层从i开始 反向*********
        //************************************************
        for (int i = s.length() - 1; i >= 0; i--) {
            dp[i][i] = 1;
            for (int j = i+1; j < s.length(); j++) {
                if (s.charAt(i) == s.charAt(j)) {
                    dp[i][j] = dp[i+1][j-1] + 2;
                } else {
                    dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1]);
                }
            }
        }
        return dp[0][s.length()-1];
    }
}


//Top bottom recursive method with memoization
//递归的方案复杂度还是比非递归要高点

public class Solution {
    public int longestPalindromeSubseq(String s) {
        return helper(s, 0, s.length() - 1, new Integer[s.length()][s.length()]);
    }

    private int helper(String s, int i, int j, Integer[][] memo) {
        if (memo[i][j] != null) {
            return memo[i][j];
        }
        if (i > j)      return 0;
        if (i == j)     return 1;

        if (s.charAt(i) == s.charAt(j)) {
            memo[i][j] = helper(s, i + 1, j - 1, memo) + 2;
        } else {
            memo[i][j] = Math.max(helper(s, i + 1, j, memo), helper(s, i, j - 1, memo));
        }
        return memo[i][j];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值