LeetCode 132. Palindrome Partitioning II (C++)
来源:互联网 发布:php高并发秒杀 实例 编辑:程序博客网 时间:2024/05/01 04:55
题目描述
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.
解题思路
首先想到的是动态规划,其次想想可否暴力求解。但是动态规划的题用暴力求解通常会超时或者超内存,事实上我在做的时候,复杂度高的动态规划仍然会超时。这道题的测试用例确实很棒,对算法复杂度要求很高。下面先从高复杂的的代码说起,逐步得到“正确”的代码。
解法一(超时):二维动归+遍历
- 求回文串:逆序判断等(非动态规划)
- 求切割数:s的子串s(i,j): s[i]…s[k-1] | s[k]…s[j]
从s[k-1]和s[k]之间分割为两部分,则s(i,j)如果不是回文串,则其最小分割的就是找一个合适的k,并在k处分割。这个合适的k需要在i到j直接遍历寻找,这就是动态规划中的遍历操作。递归方程如下:
f(i,j) = min { f(i,k-1) + f(k,j) } if s(i,j)不是回文
f(i,j) = 0 if s(i,j)是回文
上式中,s(i,j)表示s的从i到j的子串,f(i,j)表示子串s(i,j)的最小切割数。注意递归式中等式的左边有两个参数,说明是需要二维动态规划,等式右边有min求最小值,说明需要遍历,此即为二维动归+遍历,代码非常容易写。 - 复杂度为O(n^3)
class Solution {public: int minCut(string s) { int n=s.length(); //二维数组,初值设为0,多增加一个空间,以防越界 vector<vector<int> > f(n+1,vector<int>(n+1,0)); //以子串长度为递归条件 for(int l=2;l<=n;l++) { for(int i=0;i<=n-l;i++) { int j=i+l-1; //求字符串是否为回文串 string s1=s.substr(i,l);//i为起始位置,l为长度 string s2(s1.rbegin(),s1.rend());//构造逆序串 if(s1==s2)f[i][j]=0; //如果不是回文串则遍历求最小切割数 else { f[i][j]=n;//初始化为最大值 for(int k=i+1;k<=j;k++)//注意作开右闭 f[i][j]=min(f[i][j],f[i][k-1]+f[k][j]+1) ; } } } return f[0][n-1];//从0开始 }};
解法二(Accept):
求回文串:动态规划
s(i,j)为回文串,当且仅当s[i]=s[j],并且s(i+1,j-1)是回文串。用递推方程表示为:d(i,j)=true , if s[i]=s[j]&&s(i+1,j-1)是回文串。求切割数:一维动归+备忘录
备忘录就是提前将s(i,j)是否为回文串记录在一个数组中,供动态规划查找。
动态规划采用一维+遍历方式,递推方程如下:
f(j)=min{f(j),f(i-1)+1} ,0<=i<=j,并且s(0,j)不是回文串
f(j)=0 if s(0,j)是回文串
f(j)表示s(0,j)的最小切割数。
s的子串s(0,j) : s[0]…s[i-1] | s[i]…s[j]- 时间复杂度O(n^2).
class Solution {public: int minCut(string s) { int n=s.length(); //回文字串备忘录,记录是子串是否为回文串,初值为false vector<vector<bool> > p(n+1,vector<bool>(n+1,false)); for(int j=0;j<n;j++) { for(int i=j;i>=0;i--) p[i][j]=p[i][j]||(s[i]==s[j]&&(j-i<=1||p[i+1][j-1])); } vector<int> f(n+1,0); for(int i=0;i<n;i++) f[i]=i; for(int j=0;j<n;j++)//正序递归 { for(int i=j;i>=0;i--)//逆序递归 { if(p[i][j]) { if(i==0) f[j]=0; else f[j]=min(f[j],f[i-1]+1); } } } return f[n-1]; }};
- LeetCode 132. Palindrome Partitioning II (C++)
- 【C++】LeetCode 132. Palindrome Partitioning II
- LeetCode 132. Palindrome Partitioning II
- [LeetCode]132.Palindrome Partitioning II
- [Leetcode] 132. Palindrome Partitioning II
- [leetcode] 132.Palindrome Partitioning II
- Leetcode 132. Palindrome Partitioning II
- LeetCode 132. Palindrome Partitioning II
- Leetcode 132. Palindrome Partitioning II
- [LeetCode] 132. Palindrome Partitioning II
- 132. Palindrome Partitioning II, leetcode
- [LeetCode]132. Palindrome Partitioning II
- Leetcode 132. Palindrome Partitioning II
- [LeetCode]132. Palindrome Partitioning II
- 【LeetCode】132.Palindrome Partitioning II
- Leetcode 132. Palindrome Partitioning II
- LeetCode 132. Palindrome Partitioning II
- leetcode 132. Palindrome Partitioning II
- ListView隐藏右侧滚动条
- 设计模式解析之代理模式
- C++递归算法:我的理解
- parallels deskop for mac
- HTML中的<label>标签
- LeetCode 132. Palindrome Partitioning II (C++)
- Java基本数据类型
- RxJava 方法备忘录
- 从张帅进入澳网女子八强来谈我的苦恼
- 2012年第三届蓝桥杯C/C++程序设计本科B组省赛
- java递归求和、倒置算法
- nyoj301——递推求值
- 【矩阵】[HNOI2011][HYSBZ/BZOJ2326][CQBZOJ2831]数学作业
- 解决webstorm卡顿问题