House Robber

1 篇文章 0 订阅

198. House Robber
题意:强盗计划沿街去盗窃每一个住户,每个房子都有一定量的现金,阻止盗窃的唯一阻碍是相邻的两个房子之间有安全系统,一旦这两个房子同时被盗窃,系统就会自动联系警察。给定一系列非负整数代表每个房子的金钱,求出再不惊动警察的情况下能盗窃到的最大值。
方法一:
一维DP, 当前最大值相当于Math.max(nums[i - 1],nums[i] + nums[i - 2]),处理一下边界情况

public class Solution {
    public int rob(int[] nums) {
        if(nums == null || nums.length == 0)
            return 0;

        for(int i = 0; i < nums.length; i++){
            int temp1 = i - 1 < 0 ? 0 : nums[i - 1];
            int temp2 = i - 2 < 0 ? 0 : nums[i - 2];
            nums[i] = Math.max(temp1, nums[i] + temp2);
        }

        return nums[nums.length - 1];
    }
}

方法二:
可以使用和climbing stairs类似的方法,用三个变量来保存临时结果。robLast和notRobLast分别代表 i - 1步和i - 2步。

public class LeetCode198 {
    public int rob(int[] nums) {
        if(nums == null || nums.length < 1) return 0;
        if(nums.length == 1) return nums[0];
        int nolast = 0;
        int last = 0;
        int prefit = 0;
        for (int i = 0; i < nums.length; i++) {
             prefit = Math.max(last, nolast + nums[i]);
             nolast = last;
             last = prefit;
        }
        return Math.max(nolast, last);
    }
}

方法三:
设定两个变量,分别表示选择了当前的房子和没有选择当前的房子

public class Solution {
    public int rob(int[] nums) {
        int best0 = 0;                      //choose current house
        int best1 = 0;                      // do not choose current house
        for(int i = 0; i < nums.length; i++){
            int temp = best0;
            best0 = Math.max(best0, best1);
            best1 = temp + nums[i];
        }
        return Math.max(best0, best1);
    }
}

213. House Robber II
题意:强盗计划沿街去盗窃每一个住户,每个房子都有一定量的现金,阻止盗窃的唯一阻碍是相邻的两个房子之间有安全系统,一旦这两个房子同时被盗窃,系统就会自动联系警察。给定一系列非负整数代表每个房子的金钱,求出再不惊动警察的情况下能盗窃到的最大值,其中所有房子是环形结构,即第一间和最后一间有安全系统。
方法一:
像House Robber I 中方法二一样,使用动态规划法,rob(nums, 0, nums.length - 2) 代表不抢最后一家,rob(nums, 1, nums.length - 1) 代表不抢第一家,

public class Solution {
    public int rob(int[] nums) {
        if (nums == null) return 0;
        if (nums.length == 1) return nums[0];

        return Math.max(rob(nums, 0, nums.length - 2), rob(nums, 1, nums.length - 1));
    }

    private int rob(int[] nums, int lo, int hi) {
        int res = 0, robLastHouse = 0, notRobLast = 0;
        for (int i = lo; i <= hi; i++) {
            res = Math.max(robLastHouse, notRobLast + nums[i]);
            notRobLast = robLastHouse;
            robLastHouse = res;
        }
        return res;
    }
}

337. House Robber III
题意:强盗计划沿街去盗窃每一个住户,每个房子都有一定量的现金,房子布局呈树状结构,阻止盗窃的唯一阻碍是相邻的两个房子之间有安全系统,一旦这两个房子同时被盗窃,系统就会自动联系警察。给定一系列非负整数代表每个房子的金钱,求出再不惊动警察的情况下能盗窃到的最大值。
思路:
像House Robber I 中方法三一样,使用动态规划法,对于每个节点,使用两个变量,res[0], res[1],分别表示不选择当前节点子树的数值和,选择当前节点子树的数值和,动态规划的思想,然后递归。

public class Solution {
     public int rob(TreeNode root) {
         int[] res = num(root);
         return Math.max(res[0], res[1]);
     }
     public int[] num(TreeNode root){
         if(root == null) return new int[2];
         int[] res = new int[2];
         int[] left = num(root.left);
         int[] right = num(root.right);
         // res[0]代表选择当前节点,res[1]代表不选择当前节点,以下是动态规划方程式
         res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
         res[1] = root.val + left[0] + right[0];
         return res;         
     }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值