• 198. 打家劫舍


    题目

    你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警

    给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。

    示例 1:

    输入: [1,2,3,1]
    输出: 4
    解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
         偷窃到的最高金额 = 1 + 3 = 4 。

    示例 2:

    输入: [2,7,9,3,1]
    输出: 12
    解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
         偷窃到的最高金额 = 2 + 9 + 1 = 12 。

    分析

    1、首先想一想如果是暴力如何做?
    假设从最后一家店铺开始抢,那么只会遇到2种情况,即:抢这家店和下下家店,或者不抢这家店。所以我们得到递归的公式:
     Math.max(solve(nums,index-1),solve(nums,index-2)+nums[index]); 

    执行结果如下图,我们看到递归有很多重复计算。我们可以用一个数组来记录已经计算过的结果,再次碰到的时候直接返回。

    实现1 - 暴力递归

    var rob = function(nums) {
        return solve(nums,nums.length-1);
    };
    function solve(nums,index){
        if(index<0) return 0 ;
        return Math.max(solve(nums,index-1),solve(nums,index-2)+nums[index]);
    }

    实现2 - 递归去冗余,记忆化搜索

    var rob = function(nums) {
        //用ret来保存结果,初始化为-1
        this.ret=[];
        for(var i=0 ;i<nums.length;i++){
            this.ret.push(-1)
        }
        return solve(nums,nums.length-1);
    };
    function solve(nums,index){
        if(index<0) return 0 ;
        //因为初始化-1,所以有解的结果就直接返回。
        if(this.ret[index]>=0) return this.ret[index]; 
        //每次递归把当前的结果保存到ret中
        this.ret[index]=Math.max(solve(nums,index-1),solve(nums,index-2)+nums[index]);
        //返回每一次Math.max(...)的结果
        return this.ret[index];
    }

     实现3 - 动态规划

    /**
        1.dp[i]表示当前状态的最优解,即打劫到第i家时获得的最高金额。
        2.每个状态有两种情况。
            ①打劫第i家:dp[i-2] + nums[i],表示根据上上家的最优解(最高价值)计算得到当前最优解。
            ②不打劫第i家:dp[i-1],表示任然延续上一个状态,也就是延续上一个最优解。
        3.取①和②的最大值作为当前最优解。
     */
    var rob = function(nums) {
        
        var len=nums.length;
        if(len===0) return 0;
        var dp = new Array(len);
        dp[0]=nums[0];
        dp[1]=Math.max(nums[0],nums[1]);
        for(var i=2;i<len;i++){
            dp[i]=Math.max(dp[i-1],dp[i-2]+nums[i]);
        }
        return dp[len-1];
    };

    运算过程如下:

    参考:https://www.jianshu.com/p/77f1e8157277

  • 相关阅读:
    向强大的SVG迈进
    手把手教你写个小程序定时器管理库
    蒲公英 · JELLY技术周刊 Vol.11 Lighthouse 测试报告生成
    ES6语法——let和const
    北京天地益星面经
    JS的数据类型你真的懂了吗
    北京MedPeer凉经
    flex布局语法+实例
    面试官问:你有多少种方式实现三栏布局?
    CSS粘性定位
  • 原文地址:https://www.cnblogs.com/remly/p/10614822.html
Copyright © 2020-2023  润新知