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. oracle学习笔记2:创建修改表

    1.创建表 CREATE TABLE ORDERINFO ( ORDERID NUMBER(*, 0) NOT NULL , ORDERCODE VARCHAR2(20 BYTE) NOT NULL ...

  2. hadoop_并行写操作思路_2

    如果想实现将 Client端的 File并行写入到 各个Datanode中, 首先, 应该修改的是,DistributedFileSystem中的create方法, 在create 内部调用FSNam ...

  3. html-----004

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. javascript之事件详解2

    1.事件对象: 在触发DOM事件的时候都会产生一个对象. 2.事件对象event: (1).type:获取事件类型 (2).target:获取事件目标 (3).stopPropagation():阻止 ...

  5. boost::xml——基本操作以及中文乱码解决方案 (续)

    本博文主要想说明以下两点: 1.对于上一篇的<boost::xml——基本操作以及中文乱码解决方案>解释,这篇博文基本解决了正确输入输出中英文问题,但是好像还没有解决修改中文出现乱码的问题 ...

  6. GridView获取单个单元格的值

    0.GridView中的所有数据都存储在Rows集合中,可以通过Rows的Cell属性获取单个单元格的值:如果某个单元格包含其他控件,则通过使用单元格的 Controls 集合,从单元格检索控件:如果 ...

  7. demo_05HTML5+CSS3绘制小鸟

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. [转] 《高性能HTML5》读后整理的Web性能优化内容

    读后感 先说说<高性能HTML5>这本书的读后感吧,个人觉得这本书前两章跟书的标题完全搭不上关系,或者说只能算是讲解了“高性能”这三个字,HTML5完全不见踪影.个人觉得作者应该首先把HT ...

  9. learn-python3

    # learn-python3   这是我初学Python时写的一套Python基础示例程序.主要基于廖雪峰老师的Python3教程和<<深入理解Python>>. 感谢! 下 ...

  10. python for list generate content

    content = [ii for ii in range(50)] This can generate a list content