算法练习-动态规划 LeetCoe 213. 打家劫舍 II

今日心情:你能做成你想做的任何事!

题目描述:

LeetCode 213. 打家劫舍 II

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

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

 


解题代码:

class Solution {
    //分两次情况求取最大值
    // 1. 从0开始到倒数第二个
    // 2. 从1开始到倒数第一个
    public int rob(int[] nums) {

        //special situations
        int len = nums.length;

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

        int maxRob = Math.max(robSingle(nums,0,len-2),robSingle(nums,1,len-1));
        return maxRob;
    }

    public int robSingle(int[] nums,int start, int end){
        // base case 
        int dp_1 = nums[start];
        int dp_2 = Math.max(dp_1,nums[start+1]);

        for(int i = start+2;i <= end;i++){
            int temp = dp_2;
            dp_2 = Math.max(dp_1+nums[i],dp_2);
            dp_1 = temp;
        }
        return dp_2;
    }


}

 解题思路:

本题实际上在 LeetCode 198. 打家劫舍 上多做了一个条件限制要求:即第一个和最后一个不能同时抢。所以就可以分开来找:

1. 从 第一个 到 倒数第二个 范围内可以 rob 的最大金额

2. 从 第二个 到 倒数第一个 范围内可以 rob 的最大金额

3. 然后再从这找到的两个最大值中的最大值,即最终能rob的最大金额值。

(1)空数组+边界判断

        int len = nums.length;

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

(2)将在一个范围内可以 rob 的最大金额 抽出来一个函数(实际上就是LeetCode 198. 打家劫舍将 遍历的范围抽出来作为参数传入)

    public int robSingle(int[] nums,int start, int end){
        // base case 
        int dp_1 = nums[start];
        int dp_2 = Math.max(dp_1,nums[start+1]);

        for(int i = start+2;i <= end;i++){
            int temp = dp_2;
            dp_2 = Math.max(dp_1+nums[i],dp_2);
            dp_1 = temp;
        }
        return dp_2;
    }

(3)然后取两种情况分别找到的两个最大金额数,然后再从中找出最大值进行返回,即为最终能rob 的最大金额数:int maxRob = Math.max(robSingle(nums,0,len-2),robSingle(nums,1,len-1));


猜你喜欢

转载自blog.csdn.net/qq_41758969/article/details/125796158