Leetcode:打家劫舍系列

Posted 一腔诗意醉了酒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode:打家劫舍系列相关的知识,希望对你有一定的参考价值。


缘起:

闲来无事,上leetcode刷刷题吧!
恰好每日一题,好家伙来了个打家劫舍,题目还有个,这不就是一个系列的吗?
开刷

打家劫舍一

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

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

示例 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 <= nums.length <= 100
0 <= nums[i] <= 400


来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/house-robber
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


class Solution {
public:
    int rob(vector<int>& nums) {
        int len = nums.size();
        int ans[105] = {0};

        if(len<=2){
            return len==1? nums[0] : max(nums[0], nums[1]);
        }        
        ans[0] = nums[0]; 
        ans[1] = max(nums[0], nums[1]);
        for(int i=2; i<len; i++){
            ans[i] = max( ans[i-1], ans[i-2]+nums[i]);
        }
        return ans[len-1];
    }
};

打家劫舍二

你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。

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

示例 1:

输入:nums = [2,3,2]
输出:3
解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。
示例 2:

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

输入:nums = [0]
输出:0

提示:

1 <= nums.length <= 100
0 <= nums[i] <= 1000


来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/house-robber-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


class Solution {
public:
    int dp[105] = {-1};
    int data[105] = { 0 };
    int len;
    int rob(vector<int>& nums) {
        len = nums.size();
        if(len==1){
            return nums[0];
        }
        for(int i=0; i<len; i++){
            data[i] = nums[i];
        }

        return max(f(0,len-2), f(1, len-1));
    }
    int f( int start, int end){
       int a = 0;
       int b = 0;
       int ans = 0;
       for(int i=end; i>=start; i--){
           ans = max( a, data[i]+b );
           b = a ;
           a = ans;
       }
       return ans;
    }
    
};

打家劫舍三

  • 递归版本
class Solution {
public:
    int rob(TreeNode* root) {
        if(!root) {
            return 0;
        }
        if(!root->left  && !root->right){
            return root->val;
        }
        
		int a = 0;
        int b = 0;
        int ans = 0;
          // 递归
        // 抢根


        a = root->val ;
        if(root->left != NULL){
            a += rob(root->left->left) + rob(root->left->right);
        }
        if(root->right != NULL){
            a += rob(root->right->left) + rob(root->right->right);
        }
     
        
        // 不抢根
        b = rob(root->left) + rob(root->right);
        ans = max(a,b);
       
        // cout<<root->val<<endl;
        return ans; 

    }
};


  • dp
struct SubtreeStatus{
    int selected;
    int notSelected;
};


class Solution {
public:
    SubtreeStatus dfs(TreeNode* node) {
        if (!node) {
            return {0, 0};
        }
        SubtreeStatus l = dfs(node->left);
        SubtreeStatus r = dfs(node->right);
        int selected = node->val + l.notSelected + r.notSelected;
        int notSelected = max(l.selected, l.notSelected) + max(r.selected, r.notSelected);
        return {selected, notSelected};
    }

    int rob(TreeNode* root) {
        auto rootStatus = dfs(root);
        return max(rootStatus.selected, rootStatus.notSelected);
    }
};

以上是关于Leetcode:打家劫舍系列的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode ---- 打家劫舍系列问题思路与题解

LeetCode ---- 打家劫舍系列问题思路与题解

写写代码系列033:打家劫舍(动态规划)

算法刷题打卡041 | 动态规划9-打家劫舍系列

经典动态规划:打家劫舍系列问题

LeetCode刷题笔记-动态规划-day3