Leecode213.打家劫舍

//你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的
//房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。 
//
// 给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,今晚能够偷窃到的最高金额。
//
// 示例 1:
// 
//输入:nums = [2,3,2]
//输出:3
//解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。
// 
//
// 示例 2: 
//
// 
//输入:nums = [1,2,3,1]
//输出:4
//解释:你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。
//     偷窃到的最高金额 = 1 + 3 = 4 。 

思路: 动态规划,假设数组有 i-2 或 i-1 个元素且这i-2个和i-1房屋的最优解已经得出,则当有第i家时对应两种情况:抢(nums[i-2] + nums[i])或不抢(nums[i-1]),则第i家的最优解为 dp[i] = Math.max(nums[i-1], nums[i-2]+num[i]);

public class DynamicRob {

    public static void main(String[] args) {
        int[] nums = new int[]{1,2,3,1};
        Integer max = rob2(nums);
        System.out.println(max);
    }

    /**
     * 打家劫舍1
     * 街道
     * @param nums
     * @return
     */
    public Integer rob1(int[] nums) {
        //动态规划
        // dp[i] = Math.max(dp[i-2]+nums[i], dp[i-1]);
        if (null == nums) {
            return 0;
        }
        int length = nums.length;
        if (length == 1) { return nums[0]; }

        int[] dp = new int[length+1];
        dp[0] = 0;
        dp[1] = nums[0];

        for (int i = 2; i<nums.length; i++) {
            dp[i] = Math.max(dp[i-2] + nums[i-1], dp[i-1]);
        }
        return dp[length];
    }

    /**
     * 环
     * @param nums
     * @return
     */
    public static Integer rob2(int[] nums) {
        //动态规划 dp[i] = Math.max(dp[i-2]+nums[i], dp[i-1]);
        if (null == nums) {
            return 0;
        }
        int length = nums.length;
        if (length == 1) { return nums[0]; }

        int[] dp = new int[length]; //第一家打
        dp[0] = 0;
        dp[1] = nums[0];
        for (int i = 2; i<nums.length; i++) {
            dp[i] = Math.max(dp[i-2] + nums[i-1], dp[i-1]);
        }

        int[] dp2 = new int[length+1]; //第一家不打
        dp2[0] = 0;
        dp2[1] = 0;
        for (int i = 2; i<nums.length; i++) {
            dp2[i] = Math.max(dp2[i-2] + nums[i-1], dp2[i-1]);
        }

        return Math.max(dp[length-1], dp2[length]);
    }

    /**
     * 二叉树
     * @param root
     * @return
     */
    public Integer rob3(TreeNode root) {
        if (null == root) {
            return 0;
        }

        Integer res1 = 0;
        res1 += root.val; //根在结果中
        if (null != root.left) {
            res1 += rob3(root.left.left) + rob3(root.left.right);
        }
        if (null != root.right) {
            res1 += rob3(root.right.left) + rob3(root.right.right);
        }

        Integer res2 = 0; //根不在结果中
        res2 += rob3(root.left) + rob3(root.right);

        return Math.max(res1, res2);

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值