题目
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是回文。
返回符合要求的 最少分割次数 。
示例 1:
输入:s = “aab”
输出:1
解释:只需一次分割就可将 s 分割成 [“aa”,”b”] 这样两个回文子串。
示例 2:
输入:s = “a”
输出:0
示例 3:
输入:s = “ab”
输出:1
提示:
1 <= s.length <= 2000
s 仅由小写英文字母组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-partitioning-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解
1.DP
预处理和上一题一样
本题要算“最少”分割次数,考虑用DP
类似,最长递增子序列
设 f[i]:[0…i]最少分割次数
递推公式: f[i] = min(f[i], f[j] + 1) 1<= j <=i
注意:其中 如果 s[0…i]已经是回文子串,则 f[i] = 0
/*** @param {string} s* @return {number}*/var minCut = function (s) {// f[i]: s[0...i]最小回文串分割次数// 预处理const n = s.lengthconst g = new Array(n).fill(0).map(val => val = new Array(n).fill(true))for (let i = n - 1; i >= 0; i--) {for (let j = i + 1; j < n; j++) {g[i][j] = s[i] === s[j] && g[i + 1][j - 1]}}const f = new Array(n).fill(Number.MAX_VALUE)for (let i = 0; i < n; i++) {if (g[0][i]) {f[i] = 0} else {for (let j = i; j >= 1; j--) {if (g[j][i]) {f[i] = Math.min(f[i], f[j - 1] + 1)}}}}return f[n - 1]};
