746. 使用最小花费爬楼梯

题目:

吐槽:1.首先作为一个动态规划的题目,我的解题方式都是先写递归版本的再改成非递归版本的,然而在网上别人的答案都直接是非递归版本,边界解释的也不清楚,最后自己一点点调试折腾了半天,感觉还是很有收获的。

2.这个题目代码虽然简单,看似是个水题,但是分的情况其实是很多的,在第一次A这种题的情况下想把代码写的很精炼我觉得难度还是很大的,所以我把各种情况的判断,分解出来。

代码:

递归版本

 int[] result;
    public int minCostClimbingStairs(int[] cost) {
         //解题的前提:人是站在-1位置上的(相对于cost来说的)
        //1.在没进入递归前的特例处理,当台阶数小于等于1的时候,直接返回0,因为可以不消耗体力直接迈过去。
        if(cost.length<=1){
            return 0;
        }
        //2.在没进入递归前的特例处理,当台阶数等于2的时候,从-1无法直接迈过去,所以在两个台阶上选择最小的那个作为返回值。
        if(cost.length ==2){
            return Math.min(cost[0],cost[1]);
        }
        //3.进入递归的算法逻辑,当cost.length的长度大于2的时候(台阶数大于2的时候),0和1号台阶必然会被踩一个。
        //result数组表示,踩在第i个台阶上,所消耗的最少体力。
        result = new int[cost.length+1];
        //计算出踩在第i个台阶上所消耗的最少的能量的数组。
        getresult(cost,cost.length);
//        for(int i = 0;i<result.length;i++){
//            System.out.println(result[i]);
//        }
//        System.out.print("================");
        //cost.length处的台阶其实是不消耗体力的,因为没有cost[cost.length]这个值。result[cost.length-1]和
        // result[cost.length-2]是两个我们需要的走路结果,因为再走1步或者2步就是无消耗到达cost.length台阶所消耗的能量。
        return Math.min(result[cost.length-1],result[cost.length-2]);
    }
    
    private int getresult(int[] cost,int count) {
         //当count>2的时候,必然会踩到cost[0]和cost[1]上,这两个返回值是递归的终止条件
        if(count == 0){
            return cost[0];
        }
        if(count == 1){
            return cost[1];
        }
        //记忆化搜索的数组,当没有计算过的值,让其保存在数组里。
        if(result[count] == 0){
            //当计算result[cost.length]的时候因为cost[cost.length]值不存在需要特殊处理cost[cost.length] == 0
            if(count == cost.length){
                result[count] = getresult(cost,count-2)+0>getresult(cost,count-1)+0?
                        getresult(cost,count-1)+cost[count-1]:getresult(cost,count-2)+cost[count-1];
            }else{
                //走两步到达count台阶所消耗的能量
                int a =getresult(cost,count-2)+cost[count];
                //走一步到达count台阶所消耗的能量
                int b = getresult(cost,count-1)+cost[count];
                //选择消耗最少的值保存在数组。
                result[count] = a>b? b:a;
            }
        }
        return result[count];
    }

动态规划版本

    int[] result;
    public static int minCostClimbingStairs(int[] cost) {
        //解题的前提:人是站在-1位置上的(相对于cost来说的),result[i]表示(i>2)踩在第i个台阶上所消耗的最少体力。
        //1.cost.length长度小于等于2的情况特殊处理
        if(cost.length<=1){
            return 0;
        }
        if(cost.length ==2){
            return Math.min(cost[0],cost[1]);
        }
        //2.动态规划初始条件填写。
        result = new int[cost.length];
        result[0] = cost[0];
        result[1] = cost[1];
        //3.计算到第i个台阶消耗最少能体力的数组。
        for(int i = 2;i<cost.length;i++){
            result[i] = Math.min(result[i-1]+cost[i],result[i-2]+cost[i]);
        }
        //4.只需要返回result[cost.length-1],result[cost.length-2]的最小值就好,因为
        //result[cost.length-1]是走到cost.length-1位置所消耗的最少体力,cost走到最后了。
        //result[cost.length-2]是走到cost.length-2位置所消耗的最少体力,可以走两步不消耗能量。
        return Math.min(result[cost.length-1],result[cost.length-2]);
    }

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值