Leetcode_198_213_HouseRobber_打家劫舍_Easy_Medium

目录

 

1. Leetcode_198_HouseRobber_打家劫舍_Easy

(1)、问题介绍

(2)、思路分析

(3)、Java代码

2. Leetcode_213_HouseRobber_II_Medium

(1)、问题介绍

(2)、思路分析

(3)、Java代码


1. Leetcode_198_HouseRobber_打家劫舍_Easy

(1)、问题介绍

   

  * 难度:Easy

     * https://leetcode.com/problems/house-robber/description/

     * 题目介绍

     * You are a professional robber planning to rob houses along a street.

     * Each house has a certain amount of money stashed, the only constraint stopping you

     * from robbing each of them is that adjacent houses have security system connected and

     * it will automatically contact the police if two adjacent houses were broken into

     * on the same night.

     *

     * Given a list of non-negative integers representing the amount of money of each house,

     * determine the maximum amount of money you can rob tonight without alerting the police.

     *

     * Example 1:

     * Input: [1,2,3,1]    Output: 4

     * Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).

     *              Total amount you can rob = 1 + 3 = 4.

     * Example 2:

     * Input: [2,7,9,3,1]   Output: 12

     * Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1).

     *              Total amount you can rob = 2 + 9 + 1 = 12.

(2)、思路分析

     * 方法1:

     *          自变量n是数组nums的最大下标;dp(n)为最大下标为n情况下抢夺的最大钱数;

     *          dp(n)有两种情况,一是选择抢nums[n],则dp(n)=dp[n-2]+nums[n];

     *                         二是不选择抢多nums[n],则dp(n)=dp[n-1];

     *          因此状态转移方程为:dp(n) = max{dp[n-2]+nums[n],dp[n-1]}; n>=2;

     *          dp(0) = nums[0];

     *          dp(1) = max(nums[0],nums[1]);

     * 方法2:

     * 这种思路是自己考虑的:

     *  如果nums数组最大下标为n,则一定要抢到n的话,对应抢到n的情况有两种:

     *   一是在抢到了n-2的基础上,二是在抢夺了n-3的基础上;

     *   即一定要抢夺n房子,则最大钱数为:dp[i] = max(dp[i-2],dp[i-3])+nums[i];

     *   这时候,相当于更新之后的nums存放的是必须抢夺该房子对应的最大钱数。

     *   最终最大钱数有两种情况:一是抢了n房子,二是没有抢n房子。

     *   返回两者最大值即可:max(dp[nums.length-1],dp[nums.length-2])。

     *

     *   两种方法的区别:方法1的dp[n]中存放的是数组最大索引为n时对应的抢夺的最大钱数,

     *                   结果返回dp[n]即可;

     *                   方法2的dp[n]中存放的是在一定抢到nums[n]的情况下,最大的钱数,

     *                   最后返回dp[n-1]和dp[n]的最大值即可。

 

 

 

(3)、Java代码

/**

     * 方法1:dp数组存放的就是当前数组长度下的最大钱数

     */

    public int rob(int[] nums) {

        if (nums == null || nums.length == 0) return 0;

        int len = nums.length;

        if (len == 1) return nums[0];

        if (len == 2) return Math.max(nums[0], nums[1]);

        int[] dp = new int[len];//存放对应最大钱数

        //初始化dp[0]、dp[1]

        dp[0] = nums[0];

        dp[1] = Math.max(nums[0], nums[1]);

        for (int i = 2; i < len; i++) {

            dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);//状态转移

        }

        return dp[len - 1];

    }



    /**

     * 方法2:dp存放必须抢该房子的情况下的最大钱数。

     */

    public int rob2(int[] nums) {

        if (nums == null || nums.length == 0) return 0;

        int len = nums.length;

        if (len == 1) return nums[0];

        if (len == 2) return Math.max(nums[0], nums[1]);

        int[] dp = new int[len + 1];//目的:腾出dp[0] = 0

        dp[1] = nums[0];

        dp[2] = nums[1];

        for (int i = 3; i <= len; i++) {

            dp[i] = Math.max(dp[i - 2], dp[i - 3]) + nums[i - 1];

        }

        return Math.max(dp[len], dp[len - 1]);

    }

2. Leetcode_213_HouseRobber_II_Medium

(1)、问题介绍

/******Leetcode_213_HouseRobber_II_Medium*******/

    /***

     * Leetcode_213_HouseRobber_II_Medium

     * 难度:Medium

     *

     * You are a professional robber planning to rob houses along a street.

     * Each house has a certain amount of money stashed. All houses at this place are arranged in a circle.

     * That means the first house is the neighbor of the last one.

     * Meanwhile, adjacent houses have security system connected and it will automatically contact

     * the police if two adjacent houses were broken into on the same night.

     *

     * Given a list of non-negative integers representing the amount of money of each house,

     * determine the maximum amount of money you can rob tonight without alerting the police.

     *

     * Example 1:

     * Input: [2,3,2]

     * Output: 3

     * Explanation: You cannot rob house 1 (money = 2) and then rob house 3 (money = 2),

     *              because they are adjacent houses.

     * Example 2:

     * Input: [1,2,3,1]

     * Output: 4

     * Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).

     *              Total amount you can rob = 1 + 3 = 4.

(2)、思路分析

* 思路分析:

     * 在Leetcode_198_HouseRobber_Easy的基础上:分成两种情况:

     * 1. 抢第一家。

     * 2. 不抢第一家。

     * 返回两种情况的较大者即可。

(3)、Java代码

/**

     * 方法1:dp数组存放的就是当前数组长度下的最大钱数

     */

    public int rob(int[] nums) {

        if (nums == null || nums.length == 0) return 0;

        int len = nums.length;

        if (len == 1) return nums[0];

        if (len == 2) return Math.max(nums[0], nums[1]);

        int[] dp = new int[len];//存放对应最大钱数

        //初始化dp[0]、dp[1]

        //抢第一家

        dp[0] = nums[0];

        dp[1] = Math.max(nums[0], nums[1]);

        for (int i = 2; i < len - 1; i++) {

            dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);//状态转移

        }

        int max1 = dp[len - 2];//保存抢第一家情况下的最大财富

        //不抢第一家

        dp[0] = 0;

        dp[1] = nums[1];

        for (int i = 2; i < len; i++) {

            dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);//状态转移

        }

        return Math.max(max1, dp[len - 1]);

    }



    /**

     * 方法2:dp存放必须抢该房子的情况下的最大钱数。

     */

    public int rob2(int[] nums) {

        if (nums == null || nums.length == 0) return 0;

        int len = nums.length;

        if (len == 1) return nums[0];

        if (len == 2) return Math.max(nums[0], nums[1]);

        int[] dp = new int[len + 1];//目的:腾出dp[0] = 0

        //抢第一家

        dp[1] = nums[0];

        dp[2] = nums[1];

        for (int i = 3; i < len; i++) {

            dp[i] = Math.max(dp[i - 2], dp[i - 3]) + nums[i - 1];

        }

        int max1 = Math.max(dp[len - 1], dp[len - 2]);//抢第一家情况下的最大财富

        //不抢第一家

        dp[1] = 0;

        dp[2] = nums[1];

        for (int i = 3; i <= len; i++) {

            dp[i] = Math.max(dp[i - 2], dp[i - 3]) + nums[i - 1];

        }

        return Math.max(max1, Math.max(dp[len], dp[len - 1]));

    }

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值