[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] 是否可以根据 PalinVV[i+1][k-1] 结果得到。对于 PalinVV 二维表格,从下往上计算,方便利用之前的结果。

vector<int> tailMinCutSC;

const int NEWONE = -1;

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()-1);
}

/**
 * 对 s 字符串 [sIdx, n]部分进行回文分割,返回最小分割情况的子字符串数。
 *
 */
int palindromeCut(const string& s, int sIdx){

    if (isPalindrome(s, sIdx)) {

        tailMinCutSC[sIdx] = 1;
        return 1;
    }

    int minCutSC = (int)s.size() - sIdx;

    for (int i = sIdx + 1 ; i < s.size(); i++) {
        bool leftP = isPalindrome(s, sIdx, i-1);
        if (leftP == false) {
            continue;
        }
        int rightSC;
        if (tailMinCutSC[i] != NEWONE) {
            rightSC = tailMinCutSC[i];
        }else{
            rightSC = palindromeCut(s, i);
            tailMinCutSC[i] = rightSC;
        }

        int oneSolution = rightSC + 1;
        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()-1; i >= 0; i--) {
        PalinVV[i][i] = 1;
    }

    for (int i = (int)s.size()-2; i >= 0; i--) {
        if (s[i] == s[i+1]) {
            PalinVV[i][i+1] = 1;
        }else{
            PalinVV[i][i+1] = 0;
        }
    }

    for (int i = (int)s.size()-3; i >= 0; i--) {
        for (int k = (int)s.size()-1; k >= i + 2; k--) {
            if (s[i] == s[k] && PalinVV[i+1][k-1]) {
                PalinVV[i][k] = 1;
            }else{
                PalinVV[i][k] = 0;
            }
        }
    }
}

int minCut(string s) {

    calculatePalinVV(s);

    vector<int> tmp(s.size(), NEWONE);
    tailMinCutSC = tmp;

    int minSC = palindromeCut(s, 0);

    tailMinCutSC[0] = minSC;

    int minCutPoint = minSC - 1;

    return minCutPoint;
}
时间: 2024-10-24 03:05:40

[LeetCode] Palindrome Partitioning II 解题笔记的相关文章

LeetCode: Palindrome Partitioning II 解题报告

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 pa

[LeetCode] Palindrome Partitioning II [12]

题目 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&qu

LeetCode: Palindrome Partitioning II [132]

[题目] 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&

[LeetCode] Palindrome Partitioning II (DP)

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"

【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&

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

[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"

leetcode题目:Palindrome Partitioning 和Palindrome Partitioning II

题目一: Given a string s, partition s such that every substring of the partition is a palindrome. Return all possible palindrome partitioning of s. For example, given s = "aab", Return [ ["aa","b"], ["a","a",

[LeetCode]132.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&qu