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.
[balabala] 这道题目的直接思路是利用Palindrome Partition的思路,利用isPalin[i][j] 递归求解,算法复杂度是O(N^N),果断超时。进一步优化,保存一个cut[][]数组,其中cut[i][j] 表示s[i,j] 对应子串的min cuts,递推式见代码,时间复杂度是O(N^3),仍然超时。最终O(N^2)的版本是一年前网上找的答案,未记录出处。不知道大神脑袋瓜怎么运转的,我能理解正确性,但想不通如何得到这种优化思路的。method3是直接参考的,method4我就反了个求解顺序,原理同method3一样,若是自己想估计会写成method4的样子。貌似自己该多练习逆向思考。method3 和 method4中dp数组多开了一个,并且每个元素比真实值多1,这是个编码技巧,可以避免for循环中判断边界条件,一开始自己不能体会作者用意,dp数组不多开元素保持真实值,会得到wrong answer,带进代码debug下就能理解了。
public class Solution { // Method 5: 重做时自己的写法 public int minCut(String s) { if (s == null || s.length() == 0) return 0; int n = s.length(); boolean[][] isPalin = new boolean[n][n]; for (int i = 0; i < n - 1; i++) { isPalin[i][i] = true; isPalin[i][i + 1] = s.charAt(i) == s.charAt(i + 1); } isPalin[n - 1][n - 1] = true; for (int l = 3; l <= n; l++) { for (int i = 0; i + l <= n; i++) { int j = i + l - 1; isPalin[i][j] = s.charAt(i) == s.charAt(j) && isPalin[i + 1][j - 1]; } } if (isPalin[0][n - 1]) return 0; int[] dp = new int[n]; for (int i = 0; i < n; i++) { if (!isPalin[0][i]) { dp[i] = n; for (int j = 0; j < i; j++) { if (isPalin[j + 1][i]) dp[i] = Math.min(dp[i], dp[j] + 1); } } } return dp[n - 1]; } // dp[i]:s.substring(0, i)需要的min cuts public int minCut(String s) { if (s == null || s.length() == 0) return 0; int n = s.length(); boolean[][] isPalin = new boolean[n][n]; int[] dp = new int[n + 1]; for (int i = 1; i <= n; i++) dp[i] = i; for (int i = 0; i < n; i++) { for (int j = i; j >= 0; j--) { if (s.charAt(i) == s.charAt(j) && (i - j < 2 || isPalin[i - 1][j + 1])) { isPalin[i][j] = true; dp[i + 1] = Math.min(dp[i + 1], dp[j] + 1); } } } return dp[n] - 1; } // O(N^2) // dp[i]: s.substring(i, n) 需要的min cuts // dp[i] = min(dp[j] + 1), j > i // dp数组多加个元素的好处是dp[i] = Math.min(dp[i], dp[j + 1] + 1); 这一行不需要对下标进行检查 public int minCut3(String s) { if (s == null || s.length() == 0) return 0; int n = s.length(); boolean[][] isPalin = new boolean[n][n]; int[] dp = new int[n + 1]; for (int i = 0; i <= n; i++) dp[i] = n - i; for (int i = n - 1; i >= 0; i--) { for (int j = i; j < n; j++) { if (s.charAt(i) == s.charAt(j) && (j - i < 2 || isPalin[i + 1][j - 1])) { isPalin[i][j] = true; dp[i] = Math.min(dp[i], dp[j + 1] + 1); } } } return dp[0] - 1; } // O(N^3) public int minCut2(String s) { if (s == null || s.length() == 0) return 0; int n = s.length(); boolean[][] dp = new boolean[n][n]; int[][] cut = new int[n][n]; for (int i = 0; i < n; i++) dp[i][i] = true; for (int i = 0; i < n - 1; i++) { if (s.charAt(i) == s.charAt(i + 1)) { dp[i][i + 1] = true; cut[i][i + 1] = 0; } else { dp[i][i + 1] = false; cut[i][i + 1] = 1; } } int j = 0; for (int len = 3; len <= n; len++) { for (int i = 0; i <= n - len; i++) { j = i + len - 1; dp[i][j] = s.charAt(i) == s.charAt(j) ? dp[i + 1][j - 1] : false; if (dp[i][j]) { cut[i][j] = 0; } else { cut[i][j] = n; for (int k = i; k < j; k++) { cut[i][j] = Math.min(cut[i][j], cut[i][k] + cut[k + 1][j] + 1); } } } } return cut[0][n - 1]; } //O(N!) public int minCut1(String s) { if (s == null || s.length() == 0) return 0; int n = s.length(); boolean[][] dp = new boolean[n][n]; for (int i = 0; i < n; i++) dp[i][i] = true; for (int i = 0; i < n - 1; i++) dp[i][i + 1] = s.charAt(i) == s.charAt(i + 1) ? true : false; int j = 0; for (int len = 3; len <= n; len++) { for (int i = 0; i <= n - len; i++) { j = i + len - 1; dp[i][j] = s.charAt(i) == s.charAt(j) ? dp[i + 1][j - 1] : false; } } return getMinCut(s, 0, dp); } private int getMinCut (String s, int start, boolean[][] dp) { int n = s.length(); if (start == n || dp[start][n - 1]) return 0; int min = n - start; for (int i = start; i < n - 1; i++) { if (dp[start][i]) { min = Math.min(min, getMinCut(s, i + 1, dp) + 1); } } return min; } }
相关推荐
javascript js_leetcode题解之132-palindrome-partitioning-ii.js
《在IDE中高效进行LeetCode练习:leetcode-editor的深度解析》 在编程学习与技能提升的过程中,LeetCode作为一款广受欢迎的在线编程挑战平台,帮助众多开发者锻炼算法思维,提高编程能力。而为了进一步提升练习体验...
leetcode-习题集资源leetcode-习题集资源leetcode-习题集资源leetcode-习题集资源leetcode-习题集资源leetcode-习题集资源
leetcode-cli-plugins leetcode-cli 的第 3 方插件。 什么是 如何使用 如何使用 插件 名称 描述 增强的命令 按公司或标签过滤问题 list 不要在同一台计算机上使 Chrome 的会话过期 login 不要在同一台计算机上使 ...
java java_leetcode-113-path-sumII
在IDE中解决LeetCode问题,支持leetcode.com与leetcode-cn.com,满足基本的做题需求。 理论上支持: IntelliJ IDEA PhpStorm WebStorm PyCharm RubyMine AppCode CLion GoLand DataGrip Rider MPS Android Studio。
LeetCode Editor 7.4 版本的下载是一个名为 "leetcode-editor" 的压缩包文件。这个压缩包的导入过程非常简单,只需要将它直接拖入 IDEA 界面,IDEA 会自动识别并安装插件。这种方式使得安装过程无需额外的步骤,对于...
c c语言_leetcode 0009_palindrome_number.zip
leetcode-习题集资源源代码leetcode-习题集资源源代码leetcode-习题集资源源代码leetcode-习题集资源源代码leetcode-习题集资源源代码
~/.vscode/extensions/leetcode.vscode-leetcode-0.17.0/node_modules/vsc-leetcode-cli/bin/leetcode /usr/local/bin/leetcode 修改模板 open ~/.vscode/extensions/leetcode.vscode-leetcode-0.17.0/node_modules/...
解题思路思路和LeetCode-python 503.下一个更大元素 II一致,只是这里求的是下标的距离,而不是数值倒序搜索,用到栈,栈里存储索引情况1:若栈为
《PyPI官网下载 | leetcode-export-1.1.tar.gz》 在编程世界里,LeetCode是一个备受程序员喜爱的在线平台,它提供了大量的算法题目,帮助开发者提升编程技能和解决问题的能力。而Python作为一门广泛使用的高级编程...
python python_leetcode题解之132_Palindrome_Partitioning_II
leetcode-cheat 的发布 它是什么 ? 这是一个chrome 扩展,可以帮助您更高效地使用 leetcode。您可以从 重要: leetcode-cheat 现在只支持中文版。 也就是说不完全支持leetcode.com,但是你可以用leetcode-cn.com代替...
js js_leetcode题解之9-palindrome-number.js
javascript js_leetcode题解之131-palindrome-partitioning.js
`swift-Swif-LeetCode-Utils` 是一个实用工具库,它为Swift程序员提供了方便快捷的方法来处理这些问题。这个项目可以帮助你更高效地进行LeetCode上的编程练习,提升你的解决方案的可读性和简洁性。 首先,让我们...
c语言入门 C语言_leetcode题解之09-palindrome-number.c
javascript js_leetcode题解之125-valid-palindrome.js