LeetCode每日一题,132. Palindrome Partitioning II
先看题目描述
大意就是给定一个字符串 s,让我们将 s 分割成多个回文子串,并返回最小的分割次数
算法和思路
动态规划
- 状态方程定义:f[i] 表示将子串 s[0:i] 分割为多个回文子串的最小分割次数
- 状态转移方程:若 s[0:i] 为回文串,则 f[i] = 0;否则 f[i] = min{f[j]} + 1,其中 0 <= j < i 且 s[j + 1:i] 为回文串
- 最后返回 f[len - 1] 即可
即我们枚举最后一个回文串的起始位置 j + 1,保证 s[j + 1:i] 是一个回文串,那么 f[i] 就可以从 f[j] 转移而来,附加一次额外的分割次数。若 s[0:i] 本身就是回文串的话,则不用分割,其最小分割次数为 0
至于如何快速的判断 s[j + 1:i] 是否为回文串,我们可以使用动态规划进行预处理
- 状态方程定义:布尔数组 dp[i][j] 表示子串 s[i:j] 是否为回文串
- 状态转移方程:dp[i][j] = dp[i + 1][j - 1] && s[i] == s[j]
将 dp 数组预先构建好后便可在 O(1) 的时间内判断子串 s[j + 1:i] 是否为回文串
ps:感觉这题中动态数组 f 的状态转移方程有点类似 LIS问题(最长上升序列问题)的状态转移方程,其状态转移方程为 f[i] = max{f[j]} + 1,其中 0 <= j < i 且 nums[j] < nums[i]
算法源码
动态规划
1 | import java.util.Arrays; |
下面是使用 回溯搜索 + 动态规划 实现的代码,基本上和昨天的题思路是一致的,结果跑超时了
1 | class Solution { |