leetcode:213. 打家劫舍 II

题目来源

题目描述

在这里插入图片描述

class Solution {
public:
    int rob(vector<int>& nums) {

    }
};

题目解析

分析数据

  • 0 <= nums[i] <= 1000,全是正数,所以应该能抢则抢

思路

leetcode:198. 打家劫舍 I本质是基于一维数组的,而【打家劫舍 II】是一个环形数组。房子0和房子N-1成为了邻居,不能同时偷。

  • 要么没有偷房子0
  • 要么没有偷房子N-1

因此,我们将原数组拆成两部分

  • nums[0],num[1]…num[end-1]
  • nums[1],nums[2]…nums[end]

然后我们分别对这两个数组求最大值,这个求解过程就完全套用了【打家劫舍 I】的逻辑。
在这里插入图片描述

思路

class Solution {
    // 至少有四家店
    // 正在决策idx, 根据上一家店是不是被抢,来决定当前店抢不抢
    // +  preStatus表示上一家店有没有被抢过
    // +  endStatus表示N - 1店有没有被抢过: 因为endStatus会影响N - 2,  所以要带上
    int process(vector<int>& nums, int idx, int preStatus, int endStatus){
        int N = nums.size();
        if(idx == N - 1){
            return  0;
        }
        
        //  N - 2店要被 preStatus和endStatus影响
        if(idx == N - 2){
            // 只要有前后两家店任何一个被抢过了,当前点就不能被抢
            if(preStatus == 1 || endStatus == 1){
                return 0;
            }
            
            int p1 = process(nums, idx + 1, 0, endStatus);
            int p2 = process(nums, idx + 1, 1, endStatus) + nums[idx] ;
            return std::max(p1, p2);
        }

        if(preStatus){  //preStatus被抢,当前店一定不能被抢
            return process(nums, idx + 1, 0 , endStatus);  //一定不能抢,  下一个决策的店是nums[idx + 1]
        }else{ //preStatus为false,当前店可以抢也可以不抢
            int p1 = process(nums, idx + 1, 0, endStatus );//一定不抢,  下一个决策的店是nums[idx + 1]
            int p2 = process(nums, idx + 1, 1 , endStatus) + nums[idx] ;  //可以抢
            return std::max(p1, p2);
        }
    }
public:
    int rob(vector<int>& nums) {
        int N = nums.size();
        if(N == 0){
            return 0;
        }

        if(N == 1){
            return nums[0];
        }

        if(N == 2){
            return std::max(nums[0], nums[1]);
        }

        if(N == 3){
            return std::max(nums[2], std::max(nums[0], nums[1]));
        }


        // 至少有4个店
        // arr[0]比较特殊,它的前一家店是arr[N - 1]
        // 将arr[0] 和arr[N - 1]绑定到一起
        // 能做决策的店: 1 ~ N - 2
        int p1 = nums[0] + process(nums, 1, 1, 0);     // 1xxxx0
        int p2 = process(nums, 1, 0, 1) + nums[N - 1];// 0xxxx1
        int p3 = process(nums, 1, 0, 0);              // 0xxxx0
        return std::max(p1, std::max(p2, p3));
    }
};

超时了,来优化的话就加缓存

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值