您的位置:首页 > 其它

[LeetCode133]Palindrome Partitioning II

2014-05-31 01:29 585 查看
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.

For example, given s =
"aab"
,

Return
1
since the palindrome partitioning
["aa","b"]
could
be produced using 1 cut.

Analysis:

This is a DP problem! Also it is a double DP problem!

Why? Because, if we use the same algorithm in the Palindrome
Partitioning I, definitely it will expire the time limit. When you are facing the problem asking "return the minimum/maximum,
best, shortest...", it is also a good direction targeting the DP (sometimes greedy also works fine). If you are not familiar with DP problem, here is
a very good reading from topcoder. Generally speaking, DP is not very easy, and most of the company interviews
will NOT cover the DP, so don't worry too much.

For this problem, firstly we consider the main part.

It is a good way to look for the "state", and the "optimal solution" based on that state, to solve the DP problem. In
other words, if you found the correct state, and the function of the state representing the optimal solution, all you need is some loops and initialization implementing the algorithm.

Here the state is not too hard ---- minimum cut. Define res[i] = the minimum cut from 0 to i in the string.

The result w =e need eventually is res[s.size()-1].

We know res[0]=0. Next we are looking for the optimal solution function f.

For example, let s = "leet".

f(0) = 0; // minimum cut of str[0:0]="l", which is a palindrome, so not cut is needed.

f(1) = 1; // str[0:1]="le" How to get 1?

f(1) might be: (1) f(0)+1=1, the minimum cut before plus the current char.

(2) 0, if str[0:1] is a palindrome (here "le" is not )

f(2) = 1; // str[0:2] = "lee" How to get 2?

f(2) might be: (1) f(1) + 1=2

(2) 0, if str[0:2] is a palindrome (here "lee" is not)

(3)
f(0) + 1, if str[1:2] is a palindrome, yes!

f(3) = 2; // str[0:3] = "leet" How to get 2?

f(3) might be: (1) f(2) + 1=2

(2) 0, if str[0:3] is a palindrome (here "leet" is not)

(3)
f(0) + 1, if str[1:3] is a palindrome (here "eet" is not)

(4) f(1) + 1, if str[2:3] is a palindrome (here "et" is not)

OK, output f(3) =2 as the result.

So,
the optimal function is:

f(i)
= min [ f(j)+1, j=0..i-1 && str[j:i] is palindrome

0, if str[0,i] is palindrome ]

The above algorithm works well for the smaller test cases, however for the big cases, it still cannot pass.

Why? The way we test the palindrome is time-consuming.

Also using the similar DP idea, we can construct the look-up table before the main part above, so that the palindrome
testing becomes the looking up operation. The way we construct the table is also the idea of DP.

e.g. mp[i][j]==true if str[i:j] is palindrome.

mp[i][i]=true;

mp[i][j] = true if str[i]==str[j] and (mp[i+1][j-1]==true or j-i<2 ) j-i<2 ensures the array boundary.

So, using this scheme to test the palindrome helps improve the efficiency and thus we can pass all the test cases. Details
see the code below.

java

public int minCut(String s) {
        int len = s.length();
		int []res = new int[len];
        boolean[][] pp = new boolean[len][len];
        for(int i=len-1;i>=0;i--){
        	for(int j=i;j<len;j++){
        		if(s.charAt(j)==s.charAt(i)&& (j-i<2 || pp[i+1][j-1])){
        			pp[i][j] = true;
        		}else {
					pp[i][j] = false;
				}
        	}
        }
        for(int i=0;i<len;i++){
        	int ms = len;
        	if(pp[0][i]){
        		res[i] = 0;
        	}else {
				for(int j=0;j<i;j++){
					if(pp[j+1][i] && ms>res[j]+1)
						ms = res[j]+1;
				}
				res[i] = ms;
			}
        }
        return res[len-1];
    }


c++

int minCut(string s) {
    int len = s.size();
		int* dp = new int[len+1];
		for(int i=len; i>=0; i--)
			dp[i] = len-i;
		bool** matrix = new bool*[len];
		for(int i=0; i<len; i++)
		{
			matrix[i] = new bool[len];
			memset(matrix[i], false, sizeof(bool)*len);
		}
		for(int i=len-1; i>=0; i--)
			for(int j=i; j<len; j++)
			{
				if(s[i] == s[j] && (j-i<2 || matrix[i+1][j-1]))
				{
					matrix[i][j] = true;
					dp[i] = min(dp[i], dp[j+1]+1);
				}
			}
		return dp[0]-1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: