打家劫舍系列——力扣119、213

2020-03-30  本文已影响0人  jim_8432

力扣第119题打家劫舍I

题目:

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

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

示例 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 。   

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/house-robber

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:

首先这道题的房屋是不定数,看了很多大佬采用动态规划去写,我刚开始还是有点懵,后面看了一下,其实是这样子的:

由于房子数量不能确定,所以我们以小见大去看。(采用示例二的例子)

输入[  ]时,偷窃到的金额为0

输入[2]时,偷窃到的金额为2

输入[2,7]时,最多偷窃到的金额为7

输入[2,7,9]时,偷窃到的金额为2+9或7,最多偷窃到2+9=11

输入[2,7,9,3]时,偷窃的金额是3+(7之前积累的最大的值=7)或(9以前积累的最大的值=11),这里最大的是11(9以前积累的最大的值)

输入[2,7,9,3,1]时,偷窃的金额是1+(9以前积累的值=11)或(3以前积累的值=11),这里最大的是12

因为每增加一个数就有可能有一个新的最大值产生,但是不变的是最新的一个数和上一个数是不能放在一起的,所以只能逐个位置去取最大。

代码:

 class Solution {  

                  public static int rob(int[] nums) {    

                        if(nums.length==0)return 0;   //如果房子数为空,偷窃数为0

                        if(nums.length==1)return nums[0];    //如果房子数为1时,偷窃数为数组的第一个数

                              int far=nums[0];    //离得较远的房子的最大取值

                            int near=Math.max(nums[0],nums[1]);   //离得较近的房子的最大取值

                             int temp=0;    //存储最新的最大值

                        for(int i=2;i<=nums.length-1;i++){    

                            temp=Math.max(far+nums[i],near);   

                             far=near;    

                            near=temp;    }   

                             return near;    }}


力扣第213题打家劫舍II

题目:

你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。

示例 1:

输入: [2,3,2]               输出: 4 

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

示例 2:

输入: [1,2,3,1]             输出: 4 

解释: 你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3), 偷窃到的最高金额 = 1 + 3 = 4 。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/house-robber-ii

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思想:

根据上一题可以得到结论,每增加一个数据,最大偷窃金钱数在  数据与数据前两位以前得到最高的数的和  或 数据前一位得到最高的数的和 中产生。由于题目的意思是,数据围成一个环,这时候怎么做呢,做法与之前类似,但是此处要分成两种情况,第一种情况是不取第一个数据(第一个房子),第二种情况是不取最后一个数据(最后一个房子)。这个时候符合了条件,不会同时取到第一个房子和最后一个房子。

代码:

public static int rob(int[] nums) {

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

    if(nums.length==1)return nums[0];

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

    //情况一,不取第一个房子

  int far=nums[1];

    int near1=Math.max(nums[1],nums[2]);

    int temp1=near1;

    for(int i=3;i<=nums.length-1;i++){

    temp1=Math.max(far+nums[i],near1);

    far=near1;

    near1=temp1;}

    //情况二,不取最后一个房子

    int far2=nums[0];

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

    int temp2=near2;

    for(int i=2;i<=nums.length-2;i++){

    temp2=Math.max(far2+nums[i],near2);

    far2=near2;

    near2=temp2; System.out.print(temp2+".");}

    if(near1>near2);else near1=near2;

    return near1;

    }

上一篇 下一篇

猜你喜欢

热点阅读