[LeetCode] Palindrome Partitioning I&II

    对于Palindrome Partitioning I ,题目对于时间复杂度要求不是很高(因为要求所有情况),所以直接搜索,或者先做dp获取之情两点间字符串是否回文,之后对这一步得到的二维数组进行dfs或者dp都是可以的

方法一:

public class Solution {
	public List<List<String>> partition(String s) {
		if(s.length()==0) return re; 
		dp=getDp(s);
		backtrace(0,s);
		return re;
	}
	List<List<String>> re=new ArrayList<List<String>>();
	List<String> trace=new ArrayList<String>();
	boolean[][] dp;
	public void backtrace(int k,String s){
		if(k==s.length()){
			re.add(new ArrayList<String>(trace));
			return;
		}
		for(int i=k+1;i<=s.length();i++){
			String str=s.substring(k,i);
			if(dp[k][i-1]){
				trace.add(str);
				backtrace(i,s);
				trace.remove(trace.size()-1);
			}
		}
	}
    public boolean[][] getDp(String s){
	   char[] ss=s.toCharArray();
	   boolean dp[][]=new boolean[ss.length][ss.length];
	   for(int i=0;i<ss.length;i++){
		   dp[i][i]=true;
	   }
	   for(int len=1;len<ss.length;len++){
		   for(int i=0;i<ss.length-len;i++){
			   int j=i+len;
			   if(i+1>j-1)
				   dp[i][j]=ss[i]==ss[j];
			   else
				   dp[i][j]=dp[i+1][j-1]&&ss[i]==ss[j];
		   }
	   }
	   return dp;
   }
    public static void main(String[] args) {
		Solution s=new Solution();
		System.out.println(s.partition("aab"));
	}
}

方法二(dp):  

(懒得再写一遍,所以copy他人的)

public class Solution3 {
	//dp  效率更高
    public static List<List<String>> partition(String s) {
		int len = s.length();
		List<List<String>>[] result = new List[len + 1];
		result[0] = new ArrayList<List<String>>();
		result[0].add(new ArrayList<String>());

		boolean[][] pair = new boolean[len][len];
		for (int i = 0; i < s.length(); i++) {
			result[i + 1] = new ArrayList<List<String>>();
			for (int left = 0; left <= i; left++) {
				if (s.charAt(left) == s.charAt(i) && (i-left <= 1 || pair[left + 1][i - 1])) {
					pair[left][i] = true;
					String str = s.substring(left, i + 1);
					for (List<String> r : result[left]) {
						List<String> ri = new ArrayList<String>(r);
						ri.add(str);
						result[i + 1].add(ri);
					}
				}
			}
		}
		return result[len];
	}
}


对于Palindrome Partitioning II,技巧相似,先dp,再对所得二维数组dp或者dfs:

代码:

public class Solution {
	//分析:先用dp做预处理  之后的所有操作相当于做一个从s.length()-1向前的搜索
	//注意:为了让决策树更简介 所以做预处理都将从前往后的搜索转换为从后向前
	//对于一个从后向前的搜索  最小子问题是从前向后的  所以可以通过对map进行前往后的dp或者从后向前的dfs实现
	  public int minCut(String s) {
		  if(s.length()==0) return 0;
	        boolean[][] map=getDp(s);
	        int[] dp=new int[s.length()+1];
	        for(int i=0;i<s.length();i++){//这段dp代码是可以转换为对map的dfs的
	        	dp[i+1]=i+1;
	        	for(int j=0;j<=i;j++){
	        		if(map[j][i]) dp[i+1]=Math.min(dp[j+1-1]+1,dp[i+1]);
	        	}
	        }
	        return dp[dp.length-1]-1;
 	  }
	  public boolean[][] getDp(String s){
		  boolean[][] dp=new boolean[s.length()][s.length()];
		  for(int len=0;len<s.length();len++){ //这里下标不要弄错
			  for(int i=0;i<s.length()-len;i++){
				  int j=i+len;
				  if(i==j) dp[i][j]=true;
				  else if(i==j-1){
					 dp[i][j]=s.charAt(i)==s.charAt(j);
				  }else{
					  dp[i][j]=dp[i+1][j-1]&&s.charAt(i)==s.charAt(j);
				  }
			  }
		  }
		  return dp;
	  }
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值