[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 ...
随机推荐
- LINQ 101——分组、Set、转换、Element
一.Grouping(分组) 例1:对于0-9数按被3整除的结果分组 代码: static void Linq1() { , , , , , , , , , }; var numModBy3 = fr ...
- Open judge 06月度开销
06:月度开销 总时间限制: 1000ms 内存限制: 65536kB 传送门 描述 农夫约翰是一个精明的会计师.他意识到自己可能没有足够的钱来维持农场的运转了.他计算出并记录下了接下来 N (1 ≤ ...
- Android 中 View移动总结:ViewDragHelper学习及用法详解
如上图简单呈现出两个方块后,提出一个需求: 1.拖动方块时,方块(即子View)可以跟随手指移动. 2.一个方块移动时,另一个方块可以跟随移动. 3.将方块移动到左边区域(右边区域)后放开(即手指离开 ...
- 10个必看的PHP小代码,很实用!
获取浏览器IP地址 function getRemoteIPAddress() { $ip = $_SERVER['REMOTE_ADDR']; return $ip; } 如果有代理服务器的情况下获 ...
- mysql datestamp坑
每次更改行数据,该行第一个datestamp如不赋值,会自动更新为当前时间.赋值还要注意用下new Date(time).updated_at要写在created_at前面...
- Day18 Django之路由系统、模板语言、Ajax、Model
一.路由系统 1.创建Django项目 django-admin startproject day18 cd day18 python3 manage.py startapp app01 2.app0 ...
- uboot内存分布
一.uboot的内存分布图 山人自己画的图 华清远见的图 二.如何修改编译地址 board/smdk2410/config.mk中定义有TEXT_BASE TEXT_BASE = 0x33F80000 ...
- Ipv6_Only-b
网上好多关于ipv6的资料,说半天ipv6是什么,怎么建立测试环境,,,可是没有看到具体的操作和解决的方案,这里,为大家提供一种方案,希望给大家带来帮助吧. 总的来说有三个方面需要进行检查和修改: 1 ...
- gcd 控制线程执行顺序(供参考)
dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, dispatch_get_global_qu ...
- Junit4拓展工具JCategory与Testng的Group功能比较
前言 笔者前段时间分享过一遍文章,关于如何通过引入新注解来扩展Junit4,以解决Process上的问题: JUnit扩展:引入新注解Annotation 最近在跟外面的同事聊的时候,得知Testng ...