【LeetCode】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.

For example, given s = "aab",
Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.

class Solution {
public:
    vector<vector<int>> pal;
	vector<vector<string>> res;
	int min;
	int minCut(string s)
	{
		int path = 0;
		min = s.length();
		for (int i = 0; i < s.size(); i++)
		{
			vector<int> line;
			pal.push_back(line);
		}
		for (int i = 0; i < s.length(); i++)
			ispal(s, 0, i);
		for (int i = 1; i < s.length(); i++)
		{
			ispal(s, i, s.length() - 1);
		}
		cut(0, path, s);
		return min;
	}
	void cut(int start, int path, string &s)
	{
		if (start>s.length() - 1)
		{
			min = (path - 1)<min ? (path - 1) : min;
			return;
		}
		for (int i = 0; i < pal[start].size(); i++)
		{
			int temp = path;
			temp++;
			cut(pal[start][i], temp, s);
		}
	}
	bool ispal(string &s, int start, int end)
	{
		if (start > end)
			return true;
		if (ispal(s, start + 1, end - 1) && s[start] == s[end])
		{
			pal[start].push_back(end + 1);
			return true;
		}
		else
			return false;
	}
};

但是这段程序会TLE,作为一个初学者实在想不到更好的办法了( ̄_ ̄|||) ,于是去翻了下讨论区,发现新的解法:

class Solution {
public:
    int minCut(string s) {
        int N = s.size();
        vector<int> dp(N+1,numeric_limits<int>::max());
        dp[0] = 0;
        for(int i=0;i<N;i++)
        for(int p=0;p<=1;p++)
        for(int l=0;l<=N;l++) {
            int a=i-l, b = i+l+p;
            if( a < 0 || b >= N || s[a]!=s[b] )
                break;
            dp[b+1] = min(dp[b+1],dp[a]+1);
        }
        return dp[N]-1;
    }
};

用的动态规划解法。公式为dp[j+1]=min(dp[j+1], dp[i]+1)    if (s[i] == s[j] && s[i+1] : [j-1]为回文),判定i:j是不是回文只需要s[i]==s[j]并且s[i+1] : [j-1]是回文就可以了。

dp[ i ]为到 i-1 为止的最小切割数。p控制奇偶数。若判定s[a:b]为回文,再切一刀即dp[a]+1,与dp[b+1]取最小值赋值给dp[b+1]。最后结束的时候多切一刀,因此返回dp[N]-1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值