132. Palindrome Partitioning II (分割回文串 II)

132. Palindrome Partitioning II


回文串的题目,这道题可以利用我之前的一个优化方案,我们知道回文串中有一个非常讨厌的情况就是奇偶问题,我们可以通过修改原始串达到所有的串都是一个奇数串。当中的最长回文串里面是利用间隔之间添加‘#’使得字符串都是奇数个。这道题呢依然可以利用,同时当中的思想也和刚才那道最长回文串非常相似。考虑这么一个问题:

字符串s:aabac
现在我们有两种切法,第一种我们需要从aa之间切一刀,那么剩下的abac又是一个子问题,同理我们可以从ab之间切一刀,那么剩下的bac同样也是子问题。相信我这么说小伙伴已经知道这是一个DP问题了。再提一点为什么这里一开始我说有两种切法,是应为aa已经是一个回文串,那么他就有两种切法,因为aab这三个不是回文串在目前看来(因为我们不保证在后续的字符串中aab是一个回文串的一部分,仅当前来看)我们必须要进行切分。那么我们需要找到回文串,那么回文串有一个非常好的特性那就是对称,同时现在我们又将子串变成奇数个所以这个操作将会非常操作,我们利用一个一维数组DP来保存长度为n的字符串最多需要切多少次,也就是说长度为1的字符串仅需要切0次,长度为2的字符串仅需要1次,这是我们初始化的条件,那么具体代码如下:

class Solution {
public:
	int minCut(string s) {
		string c;
		for (int i = 0; i < s.size(); i++)
		{
			c.push_back('#');
			c.push_back(s[i]);
		}
		c.push_back('#');
		int n = c.size();
		vector<int>dp(n + 1, 0);
		for (int i = 0; i <= n ; i++)
			dp[i] = i / 2 - 1;
		for (int i = 0; i <= n; i++)
			for (int j = 0; j <= i && i + j < n && c[i + j] == c[i - j]; j++)
				dp[i + j + 1] = min(dp[i + j + 1], dp[i - j] + 1);
		return dp[n];
	}
};

我们仔细看这个代码我们首先对初始字符串进行奇数化,通过添加‘#’,同时定义DP数组进行初始化,那这里为什么是i/2呢,我相信小伙伴已经明白了,这里的‘#’实际上并不存在,也就是我们对 #a 在#与a之间切一刀是不存在的,所以我们进行了除2操作。那么下面的for循环首先我们需要判断说那个条件,第一是我们关于i点对称进行扫描,那么边界问题需要注意,这个在for循环里写的已经很清楚了,那么最后dp[ i + j + 1] = min(dp[i + j + 1], dp[i - j] + 1)这个是什么思想呢,也就是说我们对于这个回文串已经知道关于i点对称那么我们对于这个回文串是不进行切分,我相信通过过看代码已经知道。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值