zoukankan      html  css  js  c++  java
  • Leetcode 198 打家劫舍

    这个题竟然是简单??其实通过率不是很高,只有40+%

    本题使用了递归或者dp,这个题深入理解可以好好体会递归和dp的区别。

    题目:

    两种方法,一种是递归,一种是dp。

    先说递归,这里必须要记忆化递归,不然时间复杂度会超,记忆化后的时间复杂度O(n),空间复杂度O(n)。

    代码:

    class Solution {
    private:
        vector<int> m_;
        int recu(vector<int> &amp;nums, int i){
            if(i < 0) return 0;
            if(m_[i] >= 0) return m_[i];
            m_[i] = max(recu(nums,i-2)+nums[i],recu(nums,i-1));
            return m_[i];
        }
    public:
        int rob(vector<int>&amp; nums) {
            //递归,用记忆性存储
            int n=nums.size();
            m_=vector<int>(n,-1);
            return recu(nums,n-1);
        }
    };
    

    其实很久没分析过递归了,下面是我个人对普通递归结构的理解。

    • 首先,递归必须有退出条件,通常是边界条件,代码中就是 if(i < 0) return 0;
    • 其次,递归必须有变化量,在这里是 i, 必须要维系其中的变化值。
    • 最后,递归容易带来资源浪费,配合记忆化存储可以减少时间的浪费。

    然后是使用dp的方法。

    class Solution {
    public:
        int rob(vector<int>&amp; nums) {
            //使用dp
            if(nums.empty()) return 0;
            int N=nums.size();
            vector<int> dp(N,0);
             
            if(N >= 1) dp[0]=nums[0];
            if(N >= 2) dp[1]=(nums[0] > nums[1]) ? nums[0] : nums[1];
             
            for(int i=2;i<N;i++){
                dp[i]=max(dp[i-2]+nums[i],dp[i-1]);
            }
            return dp[N-1];
     
        }
    };
    

    这里面的关键就是
    dp[i]=max(dp[i-2]+nums[i],dp[i-1]);
    然后关键是考虑特殊情况,也就是dp0和dp1的情况。

    可以看出,递归是函数反复自我调用的结果,而dp更聚焦于递推式,使用循环得出结果。

    为了进一步简化写法,可以把特殊情况写到三目运算符中,下面的参考 Youtube@花花酱 但是我觉得这样有些不利于理解代码。

    class Solution {
    public:
        int rob(vector<int>&amp; nums) {
            //使用dp
            if(nums.empty()) return 0;
            int N=nums.size();
            vector<int> dp(N,0);
            for(int i=0;i<N;i++){
                dp[i]=max((i>1?dp[i-2]:0)+nums[i],
                          (i>0?dp[i-1]:0));//简化写法
            }
            return dp[N-1];
        }
    };
    
  • 相关阅读:
    sychronized面试问题浅析
    打造一款属于自己的web服务器——开篇
    JVM学习总结五——性能监控及故障处理工具
    【转】Git常用命令备忘
    HTTP上传文件探究
    JVM学习总结四——内存分配策略
    JVM学习总结三——垃圾回收器
    JVM学习总结二——垃圾回收算法
    Vue生命周期中mounted和created的区别
    spring org.springframework.web.bind.annotation 常用注解
  • 原文地址:https://www.cnblogs.com/molinchn/p/13222518.html
Copyright © 2011-2022 走看看