算法设计与分析第九周leetcode作业

  1. Palindrome Partitioning II

Difficulty:Hard
Total Accepted:91K
Total Submissions:350.7K
https://leetcode.com/problems/palindrome-partitioning-ii/description/

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.

下面举个例子来表示如何通过动态规划解决这个问题
假设数组为abcbm
同时假设数组s[i][j]表示第i~j范围内的最小需要切片数
首先从i==j开始,每个字母自己都是回文数,无需切片,所以

s01234
00
10
20
30
40

接下来,把i~j长度扩大,分别求解s[0][1] ,s[1][2],s[2][3],s[3][4] 的值。

  • s[0][1] 为ab, 首先判断其不是回文数,接下来选择插片位置,在位置0之后可以插,s[0][1] =s[0][0] +s[1][1]
  • s[1][2]为bc,不是回文数,在位置1之后可以插,s[1][2] =s[1][1] +s[2][2]
  • s[2][3], s[3][4] 以此类推
s01234
001
101
201
301
40

接下来,将i~j长度扩大到3。分别求解s[0][2] ,s[1][3],s[2][4]的值。

  • s[0][2] 为abc,不是回文数,可查切片位置有两个,在位置0和1后面可加,s[0][2] =1+min{ s[0][j]+s[j+1][2], j属于{0,1} }
  • s[1][3]为bcb,为回文数,对应值为0
  • s[2][4]为cbm,s[2][4]=1+min{ s[2][j]+s[j+1][4], j属于{2,3} }
s01234
0012
1010
2012
301
40

接下来,推理过程同上,先判断对应的子字符串是否为回文数,如果是的话s[i][j]=0,否则s[i][j]=1+min{s[i][k]+s[k+1][j],i<=k<j}。直到推到最右上角的即为最终答案。
下面为源码:

class Solution {
public:
	int minCut(string s) {
		int size = s.size();
		/*生成size*size大小的二维数组*/
		int **result = new int*[size];
		for (int i = 0; i < size; i++) {
			result[i] = new int[size];
			for (int j = 0; j < size; j++) {
				result[i][j] = 100000;
			}
		}
		/*dis=j-i,即i~j包含的数字数量*/
		for (int dis = 0; dis < size; dis++) {
			for (int i = 0; i < size; i++) {
				int j = i + dis;
				if (j >= size)continue;
				if (ispalindrome(s.substr(i, dis+1))) {
					cout << "result[" << i << "][" << j << "]:" << s.substr(i, dis) << ":ispalindrome" << endl;
					result[i][j] = 0;
				}
				else {
					for (int k = i; k < j; k++) {
						cout << k << endl;
						result[i][j] = min(result[i][k] + result[k + 1][j], result[i][j]);
					}
					result[i][j]++;
				}
				cout << "result[" << i << "][" << j << "]:" << result[i][j] << endl;
			}
		}
		return result[0][size - 1];
	}
	bool ispalindrome(string str) {
		int size = str.size();
		for (int i = 0; i <= size / 2; i++) {
			if (str[i] != str[size - i - 1]) {
				return false;
			}
		}
		return true;
	}
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值