LeetCode132 分割回文串

分隔回文串>>>
在这里插入图片描述

dp[i]为字符串的前i个字符至少需要切几刀,则对于前i个字符串从前往后遍历每个位置j,若 j+1~i位置为回文的,则进行判断min(dp[j]+1,dp[i]),则可得到状态转移方程:dp[i]=min(dp[j]+1,dp[i])

/**
* 状态dp[i]:表示前缀子串s[0:i]分割成若干个回文子串所需要的最小分割次数
* 思考的方向是:
* 大问题的最优解是怎么由最小问题的最优解得到的?
*
* 即dp[i]如何与dp[i-1]、dp[i-2]、dp[i-3]、 。。。。。dp[0]建立联系的
*
* 比较容易想到的是:如果s[0:i]本身就是一个回文串,那么不用分割,。即dp[i]=0,这首先可以判断,否则需要遍历
*
* 接下来枚举所有可能分割的位置:即如果s[0:i]本身不是一个回文串,就尝试分割,枚举分割边界j
* 如果s[j+1,i]不是回文串,尝试下一个分割边界
* 如果s[j+1,i]是回文串,则dp[i]就是在dp[j[的基础上多挑一个分割
*
* 也是枚举j所有可能的位置,取所有dp[j]中最小的再加1,就是dp[i]
*
* 状态转移方唱
*
* dp[i]=Math.min(dp[j]+1,dp[i]) //其中 i ,j为字符串的索引位置 并且有j<iand j+1~i为回文字符
*
* 初始状态:单个字符一定是回文串,因此dp[0]=0
*
* 思考输出:状态转移方程可以得到,并且状态就是题目问的 dp[lem-1]
*

package BDyNamicProgramming;

import DString.Problem3;

/**
 * @Author Zhou  jian
 * @Date 2020 ${month}  2020/4/24 0024  16:48
 */
public class Problem132 {


    /**
     * 状态dp[i]:表示前缀子串s[0:i]分割成若干个回文子串所需要的最小分割次数
     *  思考的方向是:
     *      大问题的最优解是怎么由最小问题的最优解得到的?
     *
     *      即dp[i]如何与dp[i-1]、dp[i-2]、dp[i-3]、   。。。。。dp[0]建立联系的
     *
     *      比较容易想到的是:如果s[0:i]本身就是一个回文串,那么不用分割,。即dp[i]=0,这首先可以判断,否则需要遍历
     *
     *      接下来枚举所有可能分割的位置:即如果s[0:i]本身不是一个回文串,就尝试分割,枚举分割边界j
     *      如果s[j+1,i]不是回文串,尝试下一个分割边界
     *      如果s[j+1,i]是回文串,则dp[i]就是在dp[j[的基础上多挑一个分割
     *
     *      也是枚举j所有可能的位置,取所有dp[j]中最小的再加1,就是dp[i]
     *
     *      状态转移方唱
     *
     *      dp[i]=Math.min(dp[j]+1,dp[i]) //其中  i ,j为字符串的索引位置 并且有j<iand j+1~i为回文字符
     *
     *      初始状态:单个字符一定是回文串,因此dp[0]=0
     *
     *      思考输出:状态转移方程可以得到,并且状态就是题目问的 dp[lem-1]
     *
     *
     * @param s
     * @return
     */
    public int minCut(String s) {

        if(s.length()==0||s.length()==1) return 0;



        int[] dp = new int[s.length()];


        for (int i = 0; i < s.length(); i++) {
            dp[i] = i;
        }


        for(int i=1;i<s.length();i++){

            //如果从i到当前是回文的则不用加
            if (checkPalindrome(s, 0, i)) {
                dp[i] = 0;
                continue;
            }



            for(int j=0;j<i;j++){
                //判断从j+1到i是否为回文子串
                boolean flag = checkPalindrome(s,j+1,i);
                if(flag){//若为回文子串,则判断dp[i]是否需要更新
                    dp[i]=Math.min(dp[i],dp[j]+1);
                }
            }


        }
        return dp[s.length()-1];

    }



    /*
    判断是否为回文子串
     */
    private boolean checkPalindrome(String s, int left, int right) {
        while (left < right) {
            if (s.charAt(left) != s.charAt(right)) {
                return false;
            }
            left++;
            right--;
        }
        return true;
    }

    public static void main(String[] args) {
        String s = "aab";
        Problem132 problem132 = new Problem132();
        int size = problem132.minCut(s);
        System.out.println(size);
    }

}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值