[程序员代码面试指南]字符串问题-回文最少分割数(DP)

问题描述

给定一个字符串,输出把它全部切成回文子串的最小分割数。
例:str="ACDCDCDAD",输出2。

解题思路

DP

存储结构

  • dp数组dp[len+1],dp[i]表示子串str[I:len]至少需要切割几次,才能都切割成回文串。对应的,循环从右至左进行。

    • 注意 dp[i]的含义完全可以做对称更改,循环也变为从前向后即可。
    • 此外,为了保证int cutTime=dp[j+1]+1;//句的顺利执行,且dp[len-1]=0,palStr=true.dp数组多开一位,并初始化其为-1。
  • 二维boolean数组palStr[len][len]描述palStr[i][j]是否是回文串

状态转移方程

遍历j从i到len-1,若j到len-1是回文串,则dp[i]=dp[j+1]+1是候选最优解之一。故有dp[i]=min{dp[j+1]+1},i<=j<=len-1且palStr[i+1][j-1]是回文串

判断回文子串

  • 三种情况:str只有一个字符/str有两个字符且相等/str[i+1][j-1]为回文串且str[i]==str[j],这三种情况可合并写为str[i]==str[j]&&(j-i<=1||palStr[i+1][j-1])
  • 注意:我们需要在求palStr[I][j]的时候已知palStr[I+1][j+1]的值,根据dp[i]的含义及对应的循环顺序,我们可以保证该条件。经尝试,内部j的循环方向是无所谓的。

代码 时间复杂度O(n^2)

public class Main {
    public static void main(String args[]) {
        String str="acdcdcdad";
        int time=cutTimes(str);
        System.out.println(time);
    }

    public static int cutTimes(String str) {
        if(str==null||str=="") {
            return 0;
        }

        int len=str.length();
        int[] dp=new int[len+1];//
        dp[len]=-1;//
        boolean[][] palStr=new boolean[len][len];

        for(int i=0;i<len;++i) {
            for(int j=0;j<len;++j) {
                palStr[i][j]=false;
            }
        }

        for(int i=len-1;i>=0;--i) {
            dp[i]=Integer.MAX_VALUE;
            for(int j=i;j<len;++j) {
//          for(int j=len-1;j>=i;--j) {
                if(str.charAt(i)==str.charAt(j)&&(j-i<=1||palStr[i+1][j-1])) {
                    palStr[i][j]=true;
                    int cutTime=dp[j+1]+1;//
                    if(cutTime<dp[i]) {
                        dp[i]=cutTime;
                    }
                }
            }
        }
        return dp[0];
    }
}

原文地址:https://www.cnblogs.com/coding-gaga/p/10859323.html

时间: 2024-08-03 02:17:44

[程序员代码面试指南]字符串问题-回文最少分割数(DP)的相关文章

[程序员代码面试指南]字符串问题-找到包含串b所有字符的最小子串

题意 给串A和串B,找到A包含B所有出现字符(相同字符出现几次就要包含几次)的最小子串,输出子串长度 题解 维护一个窗口作为当前考察子串,使用一个hashmap记录每个字符在当前子串已出现情况.时间复杂度O(n). 代码 import java.util.HashMap; public class Main { public static void main(String args[]) { //test Node root=new Node(1); Node n1=new Node(-1);

程序员代码面试指南 IT名企算法与数据结构题目最优解 ,左程云著pdf高清版免费下载

下载地址:网盘下载 备用地址:网盘下载 内容简介  · · · · · ·这是一本程序员面试宝典!书中对IT名企代码面试各类题目的最优解进行了总结,并提供了相关代码实现.针对当前程序员面试缺乏权威题目汇总这一痛点,本书选取将近200道真实出现过的经典代码面试题,帮助广大程序员的面试准备做到万无一失.“刷”完本书后,你就是“题王”!__eol__本书采用题目+解答的方式组织内容,并把面试题类型相近或者解法相近的题目尽量放在一起,读者在学习本书时很容易看出面试题解法之间的联系,使知识的学习避免碎片化

5.21 回文最少分割数

[题目]: 给定一个字符串str,返回把str全部切成回文子串的最小分割数 举例: str="ABA" 不需要切割,str本身就是回文串,所以返回0 str="ACDCDCDAD" 最少需要切2次变成3个回文子串,比如"A","CDCDC"和"DAD",所以返回2 题目来源:左程云老师<程序员代码面试指南> 原文地址:https://www.cnblogs.com/latup/p/1020495

[程序员代码面试指南]递归和动态规划-换钱的最少货币数

题目描述 给定arr,arr中所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim,求组成aim的最少货币数. 解题思路 dp[i][j]表示只用第0到i种货币,凑成j元的最小货币张数. 初始化: 转移方程: dp[i][j]=min{dp[i-1][j-k*arr[i]]+k} (k>=0) 整理得 dp[i][j]=min{dp[i-1][j],min{dp[i-1][j-k*arr[i]]+k}} (k>=1) 变换得 dp[i][j]=

《程序员代码面试指南》第八章 数组和矩阵问题 将正方形矩阵顺时针转动90

题目 将正方形矩阵顺时针转动90 java代码 package com.lizhouwei.chapter8; /** * @Description: 将正方形矩阵顺时针转动90 * @Author: lizhouwei * @CreateDate: 2018/4/28 22:16 * @Modify by: * @ModifyDate: */ public class Chapter8_2 { public void rotate(int[][] matrix) { int tR = 0; i

《程序员代码面试指南》第八章 数组和矩阵问题 需要排序的最短子数组长度

题目 需要排序的最短子数组长度 java代码 package com.lizhouwei.chapter8; /** * @Description: 需要排序的最短子数组长度 * @Author: lizhouwei * @CreateDate: 2018/4/29 8:03 * @Modify by: * @ModifyDate: */ public class Chapter8_5 { public int getMinLength(int[] arr) { if (arr == null

《程序员代码面试指南》第八章 数组和矩阵问题 &quot;之&quot;字形打印矩阵

题目 "之"字形打印矩阵 java代码 package com.lizhouwei.chapter8; /** * @Description: "之"字形打印矩阵 * @Author: lizhouwei * @CreateDate: 2018/4/28 22:53 * @Modify by: * @ModifyDate: */ public class Chapter8_3 { public void printMatrixZigZag(int[][] matri

《程序员代码面试指南》第八章 数组和矩阵问题 自然数数组的排序

题目 自然数数组的排序 java代码 package com.lizhouwei.chapter8; /** * @Description: 自然数数组的排序 * @Author: lizhouwei * @CreateDate: 2018/5/8 20:51 * @Modify by: * @ModifyDate: */ public class Chapter8_14 { public void sort(int[] arr) { int left = 0; int right = arr.

《程序员代码面试指南》第八章 数组和矩阵问题 不包含本位置值的累乘数组

题目 不包含本位置值的累乘数组 java代码 package com.lizhouwei.chapter8; /** * @Description: 不包含本位置值的累乘数组 * @Author: lizhouwei * @CreateDate: 2018/5/9 21:11 * @Modify by: * @ModifyDate: */ public class Chapter8_22 { public int[] product(int[] arr) { int[] res = new in