Palindrome在记忆步骤中对DP复杂性问题进行分区

时间:2017-01-09 21:51:05

标签: java algorithm palindrome

我有以下问题:

  

给定一个字符串s,分区s使得每个子字符串   分区是回文。

     

返回s的回文分区所需的最小切割。

我得到了正确的解决方案,但我错过了优化步骤,尤其是DP中需要的记忆步骤。

public int minCut(String a)   {
    if (isValidPal(a)) {
        return 0;
    }
    return minCut(a, 0, 0);
}
int min = Integer.MAX_VALUE;
private int minCut(String a, int cut, int index) {
    // too many cuts already
    if(cut >= min) return min;
    // out of index
    if (index >= a.length()) {
        // what is left is a pal
        if (isValidPal(a)) {
            min = Math.min(min, cut);
            return cut;
        }
        return Integer.MAX_VALUE;
    }
    int newCut = Integer.MAX_VALUE;
    if (isValidPal(a.substring(0, index + 1))) {
        // then cut
        newCut = minCut(a.substring(index + 1), cut + 1, 0);
    }
    // continue either way
    newCut = Math.min(minCut(a, cut, index + 1), newCut);
    return newCut;
}
HashMap<String, Boolean> memo  = new HashMap<>();
private boolean isValidPal(String s) {
    if(memo.containsKey(s)) {
        return memo.get(s);
    }
    boolean result = true;
    for (int i = 0; i < s.length() / 2; i++) {
        if (s.charAt(i) != s.charAt(s.length() - i - 1)) {
            result =  false;
            break;
        }
    }
    memo.put(s, result);
    return result;
}

2 个答案:

答案 0 :(得分:0)

尝试添加备忘录来存储计算结果,假设您的算法正确,这应该进行优化

Map<String, Integer> dp = new HashMap<>();
private int minCut(String a, int cut, int index) {
// too many cuts already
if(cut >= min) return min;
String key = cut + " " + index;
//test if the memo contains the answer if yes return it

if(dp.containsKey(key)) return dp.get(key);
// out of index
if (index >= a.length()) {
    // what is left is a pal
    if (isValidPal(a)) {
        min = Math.min(min, cut);
        return cut;
    }
    return Integer.MAX_VALUE;
}
int newCut = Integer.MAX_VALUE;
if (isValidPal(a.substring(0, index + 1))) {
    // then cut
    newCut = minCut(a.substring(index + 1), cut + 1, 0);
}
// continue either way
newCut = Math.min(minCut(a, cut, index + 1), newCut);

//put the computed answer in the memo table
dp.put(key, newCut);
return newCut;

}

答案 1 :(得分:0)

我很抱歉,但我的回答是基于你的代码是正确的,这是一个使用memoization进行min indindrom分区的工作示例

import java.util.*;
class Main {

  static HashMap<String, Integer> memo = new HashMap<>();
  static String s;

  static int f(int i, int j){
    if(i == j) return 0;
    if(isPalindrom(s.substring(i, j))) return 0;
    String key = i + " " + j;
    if(memo.containsKey(key)) return memo.get(key);
    int ans = 999999;
    for(int k = i; k < j; k++){
      ans = Math.min(ans, f(i, k) + f(k + 1, j) + 1);
    }
    memo.put(key, ans);
    return ans;

  }
  static boolean isPalindrom(String s){
    return s.equals(new StringBuilder(s).reverse().toString());
  }
  public static void main(String[] args) {
    s = "aaka";
    System.out.println(f(0, s.length()));
  }
}