[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.
问题:对给定的字符串进行分割,使得每个子字符串都是回文的。求最小的分割情况。
假设将 s 分割为两段,[0, i-1], [i, n-1],若 [0, i-1] 为回文字符串,则 ( [i, n-1] 的最小分割次数字符串数 + 1 ) 便是 s 以 i 为分割点最小分割情况的子字符串数。
将 i 从 1 到 n-1 遍历一边,便得到 s 依次以 i 为分割点得最小分割情况的子字符串数,其中最小的便是原问题的解。
利用 DP 思路,存储中间结构,避免重复的计算。 tailMinCutSC[i] 表示从 下标i 到结尾的最小分割情况的子字符串数。
算法思路是正确的,但是扔到 LeetCode 却超时了。接下来进行多次优化:
1. 求解子问题时,将 substr 的操作改为了 传引用 & 和 下标来表示,优化效果不明显。仅从 1204 ms 加快到 936 ms 。
2. 求解 s[i, j] 是否是回文时,每次从 i 到 j 扫一遍,耗时太长。采用二维数组 PalinVV 记录全部可能的结果,减低时间复杂度。优化前的耗时我不太会分析,通过程序记录开看,是远远超过 O(n*n)的,进行这步优化后,使得整个算法时间复杂降为 O(n*n)。
3. 实现第2 步优化,本身也是一个 DP 思路。PalinVV[i][k](i <= k),表示 s[i,k] 是否是回文,可以根据 PalinVV[i+1][k-1] 结果快速得到。对于 PalinVV 二维表格,从下往上计算,方便利用之前的结果。
vector<int> tailMinCutSC; const int NEWONE = -; vector<vector<bool>> PalinVV; /**
* 判断字符串 s 的[sIdx, eIdx] 部分字符是否是回文字符串。
*
*/
bool isPalindrome(const string& s, int sIdx, int eIdx){ return PalinVV[sIdx][eIdx];
} /**
* 判断字符串 s 的[sIdx, eIdx] 部分字符是否是回文字符串。
*
*/
bool isPalindrome(const string& s, int sIdx){ return isPalindrome(s, sIdx, (int)s.size()-);
} /**
* 对 s 字符串 [sIdx, n]部分进行回文分割,返回最小分割情况的子字符串数。
*
*/
int palindromeCut(const string& s, int sIdx){ if (isPalindrome(s, sIdx)) { tailMinCutSC[sIdx] = ;
return ;
} int minCutSC = (int)s.size() - sIdx; for (int i = sIdx + ; i < s.size(); i++) {
bool leftP = isPalindrome(s, sIdx, i-);
if (leftP == false) {
continue;
}
int rightSC;
if (tailMinCutSC[i] != NEWONE) {
rightSC = tailMinCutSC[i];
}else{
rightSC = palindromeCut(s, i);
tailMinCutSC[i] = rightSC;
} int oneSolution = rightSC + ;
minCutSC = min(minCutSC, oneSolution); } return minCutSC;
} /**
* 求字符串 s 的任意子字符串是否是回文,结果存于二维布尔数组
* 求解全部可能的子字符串,符合 overlapping & optimal subcontructure,可以采用 DP 思想加速求解。
*
*/
void calculatePalinVV(string& s){ vector<vector<bool>> vvtmp(s.size(), vector<bool>(s.size())); PalinVV = vvtmp; for (int i = (int)s.size()-; i >= ; i--) {
PalinVV[i][i] = ;
} for (int i = (int)s.size()-; i >= ; i--) {
if (s[i] == s[i+]) {
PalinVV[i][i+] = ;
}else{
PalinVV[i][i+] = ;
}
} for (int i = (int)s.size()-; i >= ; i--) {
for (int k = (int)s.size()-; k >= i + ; k--) {
if (s[i] == s[k] && PalinVV[i+][k-]) {
PalinVV[i][k] = ;
}else{
PalinVV[i][k] = ;
}
}
}
} int minCut(string s) { calculatePalinVV(s); vector<int> tmp(s.size(), NEWONE);
tailMinCutSC = tmp; int minSC = palindromeCut(s, ); tailMinCutSC[] = minSC; int minCutPoint = minSC - ; return minCutPoint;
}
参考资料 :
[LeetCode] Palindrome Partitioning II, Solution, 水中的鱼
[LeetCode] Palindrome Partitioning II 解题笔记的更多相关文章
- LeetCode: Palindrome Partitioning II 解题报告
Palindrome Partitioning II Given a string s, partition s such that every substring of the partition ...
- [leetcode]Palindrome Partitioning II @ Python
原题地址:https://oj.leetcode.com/problems/palindrome-partitioning-ii/ 题意: Given a string s, partition s ...
- [LeetCode] Palindrome Partitioning II 拆分回文串之二
Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...
- Leetcode: Palindrome Partitioning II
参考:http://www.cppblog.com/wicbnu/archive/2013/03/18/198565.html 我太喜欢用dfs和回溯法了,但是这些暴力的方法加上剪枝之后复杂度依然是很 ...
- LeetCode:Palindrome Partitioning,Palindrome Partitioning II
LeetCode:Palindrome Partitioning 题目如下:(把一个字符串划分成几个回文子串,枚举所有可能的划分) Given a string s, partition s such ...
- leetcode@ [131/132] Palindrome Partitioning & Palindrome Partitioning II
https://leetcode.com/problems/palindrome-partitioning/ Given a string s, partition s such that every ...
- 【leetcode】Palindrome Partitioning II
Palindrome Partitioning II Given a string s, partition s such that every substring of the partition ...
- leetcode 131. Palindrome Partitioning 、132. Palindrome Partitioning II
131. Palindrome Partitioning substr使用的是坐标值,不使用.begin()..end()这种迭代器 使用dfs,类似于subsets的题,每次判断要不要加入这个数 s ...
- 【LeetCode】132. Palindrome Partitioning II
Palindrome Partitioning II Given a string s, partition s such that every substring of the partition ...
随机推荐
- javascript:console.log()是什么js库里的?
这个不是什么库的,这个是浏览器的函数,如果你使用firefox并且装有firebug插件,当使用console.log(……)时,会把括号内的字符串输出到控制台,当然,在IE中这个是没有的,要报错.相 ...
- ExtJs中处理时间,出现NaN-NaN-NaN的解决方式
关键字: extjs日期格式问题(二) 一般我们的前台代码Ext.grid.ColumnModel里会这样写,以便显示日期格式: Js代码 1..... 2.{header:"birth ...
- UITabBar-UITabBarItem图片的背景颜色属性和文字的颜色大小设置
UITabBarItem设置的图片选中状态下默认的是蓝色,如何改变它的颜色为图片自带的颜色呢? typedef NS_ENUM(NSInteger, UIImageRenderingMode) { / ...
- Command 模式
Command 模式通过将请求封装到一个对象(Command)中,并将请求的接受者存放具体的 ConcreteCommand 类中(Receiver)中,从而实现调用操作的对象和操作的具体实现 者之间 ...
- ACM YTU 1012 u Calculate e
u Calculate e Problem Description A simple mathematical formula for e is where n is allowed to go to ...
- Best Time to Buy and Sell Stock III 解题思路
题目要求: 最多交易两次,并且只能买卖完之后再买. 总思路: 在数组中找一个适当的点i,使得i左右两边profit之和最大. 思路: 1.从左往右扫描,left[i]记录包括i元素以内的左部的maxp ...
- 速卖通api--发起授权
<? $reqURL_onLine = "https://gw.api.alibaba.com/openapi/http/1/system.oauth2/getToken/494739 ...
- phpstorm集成phpunit(转)
转自http://blog.csdn.net/zhuziying99/article/details/49028321 phpstorm集成phpunit1.下载phpunit.phar,将该文件放到 ...
- php约瑟夫环
<?php function popChar($str , $m , $current = 0){ $number = count($str); $num = 1; if(count($str) ...
- Android Binder机制简单了解
Binder -- 一种进程间通信(IPC)机制, 基于OpenBinder来实现 毫无疑问, 老罗的文章是不得不看的 Android进程间通信(IPC)机制Binder简要介绍和学习计划 浅谈Ser ...