ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【LeetCode】132.Palindrome Partitioning II

2021-09-07 19:32:05  阅读:180  来源: 互联网

标签:Partitioning isPartition int ++ len 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.

Example 1:

Input: s = "aab"
Output: 1
Explanation: The palindrome partitioning ["aa","b"] could be produced using 1 cut.

Example 2:

Input: s = "a"
Output: 0

Example 3:

Input: s = "ab"
Output: 1

Constraints:

  • 1 <= s.length <= 2000
  • s consists of lower-case English letters only.

这种回文什么的,数据范围又小,一看就是 dp。但判断是否是回文数会很耗时间,因此我们先做一下预处理。

对于位置 i,它自身是一个回文串。然后我们向两边扩展,如果 s[i-j]==s[i+j],那么从 i-ji+j 就是个回文串。一旦出现 s[i-j]!=s[i+j],那么剩下的就一定都不是回文串了。

上面是回文串元素个数为奇数的情况,偶数的同理,判断 s[i-j]==s[i+j+1] 即可。这样我们就得到了任意字符串是否为回文串,时间复杂度 O ( n 2 ) O(n^2) O(n2)

然后就是 dp,定义 f[i] 为从 0 到 i 的子串最少要分割多少次,状态转移方程为 f[i]=min(f[i],f[j-1]+1),其中,j 到 i 的子串为回文串。初始条件为 f[0]=0。时间复杂度 O ( n 2 ) O(n^2) O(n2)

下面是代码

class Solution {
public:
    int minCut(string s) {
        bool isPartition[2001][2001];//判断是否为回文串
        int f[2001];
    	int len = s.length();
    	for (int i = 0; i < len; i++) {//回文串元素数目为奇数
        	isPartition[i][i] = true;
        	int j = 1;
        	while (i - j >= 0 && i + j < len && s[i - j] == s[i + j]) {
            	isPartition[i - j][i + j] = true;
            	j++;
        	}
        	while (i - j >= 0 && i + j < len) {
            	isPartition[i - j][i + j] = false;
            	j++;
        	}
    	}
    	for (int i = 0; i < len - 1; i++) {//回文串元素数目为偶数
        	int j = 0;
        	while (i - j >= 0 && i + j + 1 < len && s[i - j] == s[i + j + 1]) {
            	isPartition[i - j][i + j + 1] = true;
            	j++;
        	}
        	while (i - j >= 0 && i + j + 1 < len) {
            	isPartition[i - j][i + j + 1] = false;
            	j++;
        	}
    	}
    	f[0]=0;
    	for (int i = 1; i < len; i++) {//dp
        	f[i] = 9999;//取一个较大的数
        	if (isPartition[0][i])
            	f[i] = 0;
        	else
            	for (int j = 1; j <= i; j++)
                	if (isPartition[j][i])
                    	f[i] = min(f[i], f[j - 1] + 1);
    	}
    	return f[len - 1];
    }
};
StatusRuntimeMemory
Accepted16 ms10.3 MB

实际上做一做剪枝还可以更快,比如判断回文的同时就进行 dp,把最小分割次数给算出来。状态转移方程 f[i+j+1] = min(f[i+j+1],1+f[i-j])f[i+j+1] = min(f[i+j+1],1+f[i-j+1])

class Solution {
public:
    int minCut(string s) {
        int len = s.length();
        int f[len + 1];
        for (int i = 0; i <= len; i++)
            f[i] = i-1;
        for (int i = 0; i < len; i++) {
            for (int j = 0; i-j >= 0 && i+j < len && s[i-j]==s[i+j] ; j++)
                f[i+j+1] = min(f[i+j+1],1+f[i-j]);
            for (int j = 1; i-j+1 >= 0 && i+j < len && s[i-j+1] == s[i+j]; j++)
                f[i+j+1] = min(f[i+j+1],1+f[i-j+1]);
        }
        return f[len];
    }
};
StatusRuntimeMemory
Accepted4 ms6.1 MB

这下子终于全部进了前 1%

Runtime: 4 ms, faster than 99.85% of C++ online submissions for Palindrome Partitioning II.

Memory Usage: 6.1 MB, less than 99.88% of C++ online submissions for Palindrome Partitioning II.

标签:Partitioning,isPartition,int,++,len,II,132,&&,回文
来源: https://blog.csdn.net/qq_39678161/article/details/119908709

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有