LeetCode |Palindrome Partitioning I,II

    xiaoxiao2025-12-08  4

    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”,”b”] ]

    这道题还算好,不是那么变态 暴力DFS也可以通过

    class Solution { public: string s; vector<vector<string>> partition(string s) { vector<vector<string> > result; vector<string> temp; this->s=s; generate(temp,result,0); return result; } void generate(vector<string> &temp,vector<vector<string> >& result,int start){ if(start==s.size()){ result.push_back(temp); return; } for(int i=start;i<s.size();i++){ if(palindrome(s,start,i)){ temp.push_back(s.substr(start,i-start+1)); generate(temp,result,i+1); temp.pop_back(); } } } bool palindrome(string &s,int start,int end){ while(start<end && s[start]==s[end]){ start++;end--; } return start>=end; } };

    II 又是一个醉到不行的题目。 可行的剖分最少的情况。 看起来比较像DP问题。 一开始想到的思路是 对于一个串 abcbm 令dp[i][j]为i~j子序列中需要的最小切割数量,那么它可以被分为如下两种情况

    一是i~j本身为回文,则结果为0另一是本身不为回文,则结果为dp[i][j]=1+min(dp[i][k]+dp[k+1][j);即我们遍历整个i~j数组并看切分的组合哪一个最小+切分开的一次计数。理论上这种应当是O(n^3)

    这种可以优化到O(N^2) 我们从后往前推【事实上从前往后也是一样的】 当我们知道i~j是一个回文的时候,我们想知道j+1~n可以被剖分多少次。 什么意思呢, 参考地址:http://www.allenlipeng47.com/blog/index.php/2016/07/23/palindrome-partitioning-ii/ 使用一个一位数组p[i]存放0~i【以i位置结尾】的时候,即对于i长度的串最少需要切几次。

    例如这个图【不过它是从前往后推的,dp方程变成p[j]=min(p[j],p[i-1]+1】

    也就是确认了i~j是回文串之后,需要知道这个回文串之前的【i-1结尾的】需要切几次。再加上这一次的切割。 于是可以得出DP方程并写出程序…

    十分蛋疼的是int[][] 爆内存了,以后这种标记数组还是直接用一个char好了

    class Solution { public: int minCut(string s) { int n=s.size(); int p[n]; char dp[n][n]; memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++) dp[i][i]=1; for(int i=0;i<n;i++) p[i]=n-1-i; for(int i=n-1;i>=0;i--){ for(int j=i;j<n;j++){ if(s[i]==s[j]){ if(j==i+1 || j==i) dp[i][j]=1; else dp[i][j]=dp[i+1][j-1]; } if(dp[i][j]){ if(j==n-1) p[i]=0; p[i]=min(p[i],p[j+1]+1); } } } return p[0]; } }
    转载请注明原文地址: https://ju.6miu.com/read-1304739.html
    最新回复(0)