LeetCode 198. 打家劫舍

在这里插入图片描述

方法一:简单搜索(超出内存限制)

对于每一家i,选择抢或不抢,若不抢,则可对i+1进行选择;若抢,则对i+2进行选择

class Solution {
public:
    int rob(vector<int>& nums) {
        if(nums.size()==0) return 0;//空集特判
        return rec(nums,0);
    }
    int rec(vector<int>nums,int i){//从第i个住户开始rob
    	int res;
    	if(i>=nums.size()) res=0;//非法下标
    	else if(i+1>=nums.size()) res=nums[i];//若下标为最后一个,则只能抢来保证金额最大
    	else res=max(rec(nums,i+1),rec(nums,i+2)+nums[i]);//选择抢和不抢i两种情况
    	return res;
	}
};

方法二:记忆化搜索(时间和空间效率还是很差)

class Solution {
private:
	int dp[1000000];//dp数组进行记忆
public:
    int rob(vector<int>& nums) {
        memset(dp,-1,sizeof(dp));//初始化dp数组
        if(nums.size()==0) return 0;
        return rec(nums,0);
    }
    int rec(vector<int>nums,int i){//从第i个住户开始rob
    if(dp[i]>=0) return dp[i];//若已经计算过,则直接返回
    int res;
    if(i>=nums.size()) res=0;
    else if(i+1>=nums.size()) res=nums[i];
    else res=max(rec(nums,i+1),rec(nums,i+2)+nums[i]);//选择走不走i两种情况
    return dp[i]=res;//维护dp数组
}
};

方法三:穷竭搜索(超出内存限制)

class Solution {
public:
    int rob(vector<int>& nums) {
        if(nums.size()==0) return 0;
        return rec(nums,0,0);
    }
    int rec(vector<int>nums,int i,int sum){//从第i个住户开始rob
    	int res;
    	if(i>=nums.size()) res=sum;
    	else if(i+1>=nums.size()) res=nums[i]+sum;
    	else res=max(rec(nums,i+1,sum),rec(nums,i+2,sum+nums[i]));//选择走不走i两种情况
    	return res;
	}
};

方法四:动态规划(和记忆化搜索效率差不多)

class Solution {
private:
	int dp[1000000];//初始化为0
public:
    int rob(vector<int>& nums) {
        int n=nums.size();
    	for(int i=n-1;i>=0;i--){
        	if(i+1>=n) dp[i]=nums[i];
        	else dp[i]=max(dp[i+1],dp[i+2]+nums[i]); 
    	}
    	return dp[0];
    }
};

写成i正向递推,效率相同。但是若dp定义为动态数组,则效率会大大增加:

class Solution {
private:
    int dp[1000000];
public:
    int rob(vector<int>& nums) {
        int n=nums.size(); if(n==0) return 0;
        //int *dp=new int[n+1];//定义动态数组
        dp[0]=0; dp[1]=nums[0];
        for(int i=0;i<=n-2;i++) 
            dp[i+2]=max(dp[i+1],dp[i]+nums[i+1]);
        return dp[n];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值