天天看点

LeetCode——132. 分割回文串 II(Palindrome Partitioning II)[困难]——分析及代码(Java)一、题目二、分析及代码三、其他

LeetCode——132. 分割回文串 II[Palindrome Partitioning II][困难]——分析及代码[Java]

  • 一、题目
  • 二、分析及代码
    • 1. 两次动态规划
      • (1)思路
      • (2)代码
      • (3)结果
  • 三、其他

一、题目

给你一个字符串 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. 两次动态规划

(1)思路

先对字符串进行预处理,设计一个动态规划数组 dp[i][j] 表示区间 [i,j] 是否为回文子串,计算得到所有的回文区间。

再设计一个动态规划数组 minSeg[i],表示到第 i 个元素时的最小分割次数,则 minSeg[i] 的取值为:

  • 若 dp[0][i] == true,minSeg[i] = 1;
  • 否则,遍历 i 左侧的区间 [j,i],对 dp[j][i] == true 的 j,minSeg[i] = min(minSeg[j - 1]) + 1。

(2)代码

class Solution {
    public int minCut(String s) {
        char[] c = s.toCharArray();
        int n = c.length;
        boolean[][] dp = new boolean[n][n];//记录[i,j]区间是否为回文串
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                dp[i][j] = false;

        for (int i = 0; i < n; i++) {
            int oddLen = 0, evenLen = 0;
            while (i - oddLen >= 0 && i + oddLen < n && c[i - oddLen] == c[i + oddLen])//奇数长度回文串
                dp[i - oddLen][i + oddLen++] = true;
            if (i - 1 >= 0 && c[i - 1] == c[i]) {
                while (i - 1 - evenLen >= 0 && i + evenLen < n && c[i - 1 - evenLen] == c[i + evenLen])//偶数长度回文串
                    dp[i - 1 - evenLen][i + evenLen++] = true;
            }
        }
        
        int[] minSeg = new int[n];//到第i个元素时的最小分割次数
        for (int i = 0; i < n; i++) {
            minSeg[i] = i;
            if (dp[0][i] == true)
                minSeg[i] = 0;
            else {
                for (int j = 1; j <= i; j++)
                    if (dp[j][i] == true)
                        minSeg[i] = Math.min(minSeg[i], minSeg[j - 1] + 1);
            }
        }
        return minSeg[n - 1];
    }
}
           

(3)结果

执行用时 :11 ms,在所有 Java 提交中击败了 75.51% 的用户;

内存消耗 :38.7 MB,在所有 Java 提交中击败了 18.33% 的用户。

三、其他

暂无。