ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[LeetCode] 198. 打家劫舍

2020-02-25 16:37:28  阅读:281  来源: 互联网

标签:偷窃 198 int 最大值 sum1 房屋 打家劫舍 LeetCode dp


1 题目描述

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

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

示例 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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2 解题思路

  • 方法一 奇偶求和
    很容易想到要不是相邻的话,那么就是奇数和偶数各自求和取最大值,但是有点情况不是奇偶最优的,比如2,1,1,2这种需要另外一种思路,每次求和将奇数和偶数比较取最大值,然后再去相加

设置两个变量,sum0 和 sum1分别对数组的奇数和偶数元素求和。
遍历数组,索引为奇数时,将元素加到奇数和,并与偶数和比较更新成max。
偶数和同理。
返回时进行最后一次更新max。

最优解不是纯奇数和或者偶数和的情况。
这种情况下,最优解可能前半段出现在这边,后半段出现在另一边。
那么只要找到一个时机,当这一段的最优解没有另一边好时,就复制对面的最优解过来。

  • 方法二:动态规划
    动态规划方程:dp[n] = MAX( dp[n-1], dp[n-2] + num )
    由于不可以在相邻的房屋闯入,所以在当前位置 n 房屋可盗窃的最大值,要么就是 n-1 房屋可盗窃的最大值,要么就是 n-2 房屋可盗窃的最大值加上当前房屋的值,二者之间取最大值

举例来说:1 号房间可盗窃最大值为 3 即为 dp[1]=3,2 号房间可盗窃最大值为 4 即为 dp[2]=4,3 号房间自身的值为 2 即为 num=2,那么 dp[3] = MAX( dp[2], dp[1] + num ) = MAX(4, 3+2) = 5,3 号房间可盗窃最大值为 5

时间复杂度:O(n),n 为数组长度

作者:guanpengchn
链接:https://leetcode-cn.com/problems/house-robber/solution/hua-jie-suan-fa-198-da-jia-jie-she-by-guanpengchn/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

3 解决代码

  • 方法一 奇偶求和
class Solution {
    public int rob(int[] nums) {
        int sum0 = 0;
        int sum1 = 0;
        
        for(int i = 0; i < nums.length; i++ ){
            if(i % 2 == 0){
                sum0 += nums[i];
                sum0 = Math.max(sum0, sum1);
            }
            else{
                sum1 += nums[i];
                sum1 = Math.max(sum0, sum1);
            }
        }
        return  Math.max(sum0, sum1);

    }
}
  • 方法二:动态规划

class Solution {
    public int rob(int[] nums) {
        int len = nums.length;
        
        int[] dp = new int[len + 1];
        if(len == 0){
            return 0; 
        }
        dp[0] = 0;
        dp[1] = nums[0];
        
        for(int i = 2; i <= len; i++){
            dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i-1]);
        }
        return dp[len];

    }
}
你看这人,真菜 发布了255 篇原创文章 · 获赞 3 · 访问量 1万+ 私信 关注

标签:偷窃,198,int,最大值,sum1,房屋,打家劫舍,LeetCode,dp
来源: https://blog.csdn.net/qq_43584847/article/details/104499892

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有