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 解题笔记的更多相关文章

  1. LeetCode: Palindrome Partitioning II 解题报告

    Palindrome Partitioning II Given a string s, partition s such that every substring of the partition ...

  2. [leetcode]Palindrome Partitioning II @ Python

    原题地址:https://oj.leetcode.com/problems/palindrome-partitioning-ii/ 题意: Given a string s, partition s  ...

  3. [LeetCode] Palindrome Partitioning II 拆分回文串之二

    Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...

  4. Leetcode: Palindrome Partitioning II

    参考:http://www.cppblog.com/wicbnu/archive/2013/03/18/198565.html 我太喜欢用dfs和回溯法了,但是这些暴力的方法加上剪枝之后复杂度依然是很 ...

  5. LeetCode:Palindrome Partitioning,Palindrome Partitioning II

    LeetCode:Palindrome Partitioning 题目如下:(把一个字符串划分成几个回文子串,枚举所有可能的划分) Given a string s, partition s such ...

  6. leetcode@ [131/132] Palindrome Partitioning & Palindrome Partitioning II

    https://leetcode.com/problems/palindrome-partitioning/ Given a string s, partition s such that every ...

  7. 【leetcode】Palindrome Partitioning II

    Palindrome Partitioning II Given a string s, partition s such that every substring of the partition ...

  8. leetcode 131. Palindrome Partitioning 、132. Palindrome Partitioning II

    131. Palindrome Partitioning substr使用的是坐标值,不使用.begin()..end()这种迭代器 使用dfs,类似于subsets的题,每次判断要不要加入这个数 s ...

  9. 【LeetCode】132. Palindrome Partitioning II

    Palindrome Partitioning II  Given a string s, partition s such that every substring of the partition ...

随机推荐

  1. google code 上传源码

    在使用google code 的时候 做个备份, git clone https://wushuangzilong@code.google.com/p/maplebanana-proxy/ git c ...

  2. js--Ajax的小知识(二):处理ajax的session过期的请求

    问题的产生: 现如今Ajax在Web项目中应用广泛,几乎可以说无处不在. 有时会碰到这样个问题:当Ajax请求遇到Session超时,应该怎么办? 显而易见,传统的页面跳转在此已经不适用,因为Ajax ...

  3. tomcat上servlet程序的配置与处理servlet请求过程

    手动配置: tomcat服务器下web项目的基本目录结构 |-tomcat根目录 |-webapps |-WebRoot : web应用的根目录 |-静态资源(html+css+js+image+ve ...

  4. Data Abstraction

    What is an object? (Page 238) In C++, an object is just a variable, and the purest definition is &qu ...

  5. 修改hosts使用谷歌服务

    原文链接如下: http://www.findspace.name/res/72#_1

  6. jQuery源码整体结构(源码2.0.3)

    拨开jQuery的面纱,最近了解了下jQuery源码整体框架.主要包括: (1)  jQuery 核心模块 (2)  sizzle 选择器引擎 (3)  Deferred 异步队列 (4)  Supp ...

  7. 学习笔记-记ActiveMQ学习摘录与心得(一)

    这两天在看开源的MQ技术,趁着晚上安静,把这两天学的东西摘录下.在公司学东西效率真心捉鸡,心里总觉得别扭,拿了公司的钱不干活还在那学习,表示心情不淡定,效率不行啊...晚上时间是我的,下班还是蛮开心的 ...

  8. css3多行省略号

    -webkit-line-clamp 概述: -webkit-line-clamp 是一个 不规范的属性(unsupported WebKit property),它没有出现在 CSS 规范草案中. ...

  9. 指令发email

    win7下指令发送email:(telnet:不为内部指令时控制面板 -> 程序和功能 -> 打开或关闭Windows功能,如下“telnet客户端”) telnet smtp.sina. ...

  10. Xcode-01ARC / Block

    1.nonatomic 2.assign 3.strong 4.weak 5.instancetype 6.@class @property 使部分类在编译时不使用ARC -(可以让这们支持 reta ...