LeetCode 198. House Robber 递归->记忆->动态规划 ->新思路

198. House Robber

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

题意

一个专业的小偷在一条街上偷取房屋内的宝物。 每个房屋内拥有不同的价值的宝物,唯一的限制是不能连续偷取相邻房屋,否则会自动触发报警器。问如何偷取才能使得到的价值最大。

思路

这里写图片描述
这里写图片描述

代码

  • 纯递归,含大量的重复计算超时

时间复杂度:O((2^N)*N)

class Solution {
private:
    //int res; 将res放在外边会记录历史值,而出错,之前支路的值会加到旁边的支路上
    //偷取[index...n-1]房屋之间偷取宝物的最大和,index从0开始
    int robMax(vector<int>nums,int index)
    {
        if(index > nums.size())   //[index(>n-1),n-1]集合为空,表示宝物为0
            return 0;        
        int res = 0;  //所以每次都需要更新一下当前结果的最大值
        for(int i=index;i<nums.size();i++)//根节点对应的各个分支,能偷取的最大值,选分支中最大的
        {
            res = max(res,nums[i]+robMax(nums,i+2));
        }        
        return res;
    }    
public:
    int rob(vector<int>& nums) {
       return robMax(nums,0);
    }
};
  • 记忆化优化
class Solution {
private:
    vector<int> memo;
    //int res; 将res放在外边会记录历史值,而出错,之前支路的值会加到旁边的支路上
    //偷取[index...n-1]房屋之间偷取宝物的最大和,index从0开始
    int robMax(vector<int>nums,int index)
    {
        if(index > nums.size())   //[index(>n-1),n-1]集合为空,表示宝物为0
            return 0;
        if(memo[index] != -1)
        {
            return memo[index];
        }
        int res = 0;  //所以每次都需要更新一下当前结果的最大值,层层往外比较
        for(int i=index;i<nums.size();i++)  //分支
        {
            res = max(res,nums[i]+robMax(nums,i+2));
        }
        memo[index] = res;
        return res;
    }
public:
    int rob(vector<int>& nums) {
       memo = vector<int> (nums.size()+1,-1);
       return robMax(nums,0);      
    }
};
  • 动态规划,子问题最优达到全局最优。当给定的房屋有n个,范围就是[0…n),memo[i] 表示抢劫 nums[i…n) 所能获得的最大收益
  • 最小子问题就是n-1房屋,区间[n-1,n),区间内只有一个元素memo[n-1]就是第n-1房屋内的价值
  • 之后从n-2开始,区间[n-2,n),区间内有n-2和n-1两个元素,不能选相邻元素。同时需要做一个越界判断。
class Solution {
public:
    int rob(vector<int>& nums) {
       vector<int> memo(nums.size(),-1);  //记忆优化
         // memo[i] 表示抢劫 nums[i...n) 所能获得的最大收益
       memo[nums.size()-1] = nums[nums.size()-1];
       for(int i = nums.size()-2;i>= 0;i--)
       {
            for(int j = i; j<nums.size(); j++)
            {
                memo[i] = max(memo[i], nums[j] + (j + 2 < nums.size() ? memo[j + 2] : 0) );
            }

       }
       return memo[0];
    }
};

结果

这里写图片描述

新思路

class Solution {  
 public:  
     int rob(vector<int> &num) {  
         int best0 = 0;   // 表示没有选择当前houses  
         int best1 = 0;   // 表示选择了当前houses  
         for(int i = 0; i < num.size(); i++){  
             int temp = best0;  
             best0 = max(best0, best1); // 没有选择当前houses,那么它等于上次选择了或没选择的最大值  
             best1 = temp + num[i]; // 选择了当前houses,值只能等于上次没选择的+当前houses的money  
         }  
         return max(best0, best1);  
     }  
 };  
def big_countries(world: pd.DataFrame) -> pd.DataFrame是一个在pandas中定义的函数,它的参数是一个名为world的DataFrame。该函数的目的是过滤出符合条件的国家,并返回一个新的DataFrame,包含'name'、'population'和'area'这三列的数据。通过使用条件判断,将满足条件的行筛选出来,然后再选择所需的列返回。具体的实现方法有两种,一种是使用pandas写法,另一种是使用行过滤方法。在这两种方法中,都使用了与运算符(|)和比较运算符(>=)来对DataFrame进行条件判断,以筛选出符合条件的行。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【Leetcode 30天Pandas挑战】学习记录 上](https://blog.csdn.net/cwtnice/article/details/132065786)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Pandas【条件筛选】](https://blog.csdn.net/Henry_Zhao10/article/details/132050959)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值