力扣面试题46.题解

力扣面试题46.题解

在这里插入图片描述

思路

这道题是动态规划的一道很典型的问题。
从例子12258谈起。
我们可以知道,当分割成1,2,2,5,8时,
1显然只有一种分割;1,2则可以有2种,因为12<=25.
那么在1,2,2,的情况下呢?有3种分割方案。怎么算出来的呢?
我们知道,22<25,所以当后面的22捆绑在一起的时候,实际上就是看1以及1以前的数字,有多少种分割方案。
在我们声明的dp数组里,数组里存放的元素为当前元素下标下,该元素及其前面的元素组成的数字,可以分割的种类个数。
而当2和2不捆绑,分开的时候,实际上就是看前面的这个2以及2以前的数字,有多少种分割方案。
如此一来,dp[i]=dp[i-1]+dp[i-2]的状态转移方程就出来了。
特别注意的是,当遍历到8,发现58>25时,元素8的的dp数组值,实际上就是依赖于1,2,2,5的分割数目,即dp[i]=dp[i-1].
i-2小于0时怎么办?比如1,2.我们可以知道1,2捆绑一起后,就没有元素了,所以dp[i-2]=0,不必加上去(本来也越界了),此时只依赖于dp[i-1]。12<25,自然两者可以捆绑,因此dp[i]=dp[i-1]+1.加上的1,实际上就是可以捆绑的一种分割。

代码

class Solution {
public:
    int translateNum(int num) {
        if(num==0)return 1;//数字为0 显然只能分割一份
        vector<int> a;
        while(num>0){
            a.push_back(num%10);
            num/=10;
        }
        reverse(a.begin(),a.end());//此时数组a存放的是分割的一个一个数字
        vector<int> dp(a.size(),0);//建立dp数组
        dp[0]=1;
        for(int i=1;i<a.size();i++){
            int tmp=a[i-1]*10+a[i];
            if(tmp==a[i]){
                dp[i]=dp[i-1];//这是一个特殊情况,表明前一个元素是0,比如101这个例子。由报错系统可以看出,1,01这种分割是不被允许的。可能是因为01表示的不是1,而是八进制下的数的原因。因此遇到这种情况时,我们直接跳过1,01这种情况:即01不捆绑在一起了,删去等式的dp[i-2]。
            }
            else {
                    if(tmp<=25){
                    if(i-2>=0){
                        dp[i]=dp[i-1]+dp[i-2];
                    }
                    else {
                        dp[i]=dp[i-1]+1;
                    }
                }
                else {
                    dp[i]=dp[i-1];
                }
            }
            
        }
        return dp[a.size()-1];//最后的dp值即为全部元素的分割种类数
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值