leetcode132 Palindrome Partitioning II 最小分割数

题目:

Given a string s, partition s such that every substring of the partition is a palindrome.

Return the minimum cuts needed for a palindrome partitioning of s.

Example:

Input: "aab"
Output: 1
Explanation: The palindrome partitioning ["aa","b"] could be produced using 1 cut.

首先看我的第一种解法:(废了很长时间,做题太少了,动脑太少了),这个运行时间蛮短的

package test;

public class LC132Try3
{
	public int minCut(String s)
	{
		int len = s.length();
		int[] dp = new int[len];
		char[] arr = s.toCharArray();
		//最多需要分j次
		for (int j = 0; j < len; j++)
		{
			dp[j] = j;
		}
		for (int i = 0; i < len; i++)
		{
			int m = i - 1;
			int n = i + 1;		
			
			while (m >= 0 && n < len)
			{

				if (arr[m] == arr[n])
				{
                    //如果是0则没有必要分割,不需要加1
					if (m == 0)
					{
						dp[n] = Math.min(dp[n], dp[m]);
					}
					else
					{
						dp[n] = Math.min(dp[n], dp[m - 1] + 1);
					}					

					m--;
					n++;
				}
				else
				{
					//如果和他后面的不相同,则更新下后面的,最多就是他前面的加1,防止他就是自己对应自己,自己单独分割
					dp[n] = Math.min(dp[n], dp[n-1] + 1);
					break;
				}
			}
			m = i;
			n = i + 1;
			while (m >= 0 && n < len)
			{
				if (arr[m] == arr[n])
				{

					if (m == 0)
					{
						dp[n] = Math.min(dp[n], dp[m]);
					}
					else
					{
						dp[n] = Math.min(dp[n], dp[m - 1] + 1);
					}					
					m--;
					n++;
				}
				else
				{
					dp[n] = Math.min(dp[n], dp[n-1] + 1);
					break;
				}
			}

		}

		return dp[len - 1];

	}

	public static void main(String[] args)
	{
		LC132Try3 t = new LC132Try3();
		System.out.println(t.minCut("aaa"));
		//System.out.println(t.minCut("eegiicgaeadbcfacfhifdbiehbgejcaeggcgbahfcajfhjjdgj"));
		// System.out.println(t.minCut("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));

	}

}

这种解法就是对应131图的解法,下面是图的另一种解法:这个也蛮烧脑的(just for me),不知道为什么他的运行时间更慢一点(这个就是左程云的回文最少分割数),我只是改成顺序了,但现在觉得还是逆序好。

package test;

public class LC132Try4
{
	public int minCut(String s)
	{
		int len = s.length();		
		if(s==null || len==0){
			return 0;
		}
		char[] arr= s.toCharArray();
		int[] cost=new int[len];
		boolean[][] dp=new boolean[len][len];
		for(int i=0;i<len;i++){//我这个是顺序,其实逆序更好,就不用判断j==0种情况了。
			cost[i]=i;
			for(int j=i;j>=0;j--){
				if(arr[j]==arr[i]&&( i-j<2 || dp[i-1][j+1] )){
					dp[j][i]=true;
					if(j==0){
						cost[i]=0;
					}else{
						cost[i]=Math.min(cost[i],cost[j-1]+1);
					}
					
				}
			}
		}
		return cost[len-1];
	}
	
	public static void main(String[] args)
	{
		LC132Try4 t = new LC132Try4();
		//System.out.println(t.minCut("aaa"));
		System.out.println(t.minCut("eegiicgaeadbcfacfhifdbiehbgejcaeggcgbahfcajfhjjdgj"));
		// System.out.println(t.minCut("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));

	}

}

这道题解法到此结束,哈哈,来看下,我的超时解法:

package test;


public class LC132Try2
{
	public int minCut(String s)
	{
		int len=s.length();
		int ret=len-1;
		if(len==0){
			return ret;
		}
		boolean[][] temp=new boolean[len][len];
		setPalindrome(s,temp,len);
		ret=getPalindrome(s,temp,len,0);
		return ret;
		
	}
	public int getPalindrome(String s,boolean[][] temp,int len,int start){
		if(start>=len){
			return 0;
		}
		int ret= len-start-1;
		for(int i=start;i<len;i++){			
			if(temp[start][i]){
				if(i==len-1){
					return 0;
				}
				int cost=getPalindrome(s,temp,len,i+1);
				ret=Math.min(ret, cost+1);
			}
		}
		return ret;
	}
	public void setPalindrome(String s,boolean[][] temp,int len){
		char[] arr= s.toCharArray();
		for(int i=0;i<len;i++){
			temp[i][i]=true;
			int m=i-1;//即以arr[i]为中间的回文;
			int n=i+1;
			while(m>=0&&n<len){
				if(arr[m]==arr[n]){
					temp[m][n]=true;
					m--;
					n++;
				}else{
					break;
				}
			}
			m=i;//与i对称的回文;
			n=i+1;
			while(m>=0&&n<len){
				if(arr[m]==arr[n]){
					temp[m][n]=true;
					m--;
					n++;
				}else{
					break;
				}
			}
		}
	}
	public static void main(String[] args)
	{
		LC132Try2 t = new LC132Try2();
		System.out.println(t.minCut("aba"));
		
	}

}

哈哈

package test;

import java.util.HashMap;
import java.util.Map;



public class LC132Try1
{
	public int minCut(String s)
	{
		Map<String,Integer> map = new HashMap<String,Integer>();
        int ret= minCost(s,map);
        return ret;
	}
	
	public int minCost(String s,Map<String,Integer> map)
	{
		if(map.containsKey(s)){
			return map.get(s);
		}
		int len = s.length();
		int ret = len - 1;		
		char[] arr=s.toCharArray();
		char c=arr[0];
		for(int i=0;i<arr.length;i++){
			if(arr[i]==c){
				String t=s.substring(0, i+1);
				if(isPalindrome(t)){
					if(i==arr.length-1){
						ret= 0;
					}else{
						int cost=minCost(s.substring(i+1),map);
						map.put(s.substring(i+1), cost);
						ret=Math.min(ret,cost+1) ;						
					}
									
				}
			}
		}
		return ret;

	}
	
	
	public boolean isPalindrome(String s){		
		int len=s.length();
		if(len==0){
			return false;
		}		
		char[] arr=s.toCharArray();
		for(int i=0;i<len/2;i++){
			if(arr[i]!=arr[len-i-1]){
				return false;
			}
		}
		return true;
	}
	
	
}

猜你喜欢

转载自blog.csdn.net/ata_123/article/details/80695975