`

Leetcode - House Robber

阅读更多

[题目] 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.

[分析]

一维动态规划,记num[i]对应的最大安全盗金为safe[i], 递推式为safe[i] = max(safe[i-1], safe[i-2] + num[i])。

实现时仅需一个三元数组,循环使用.

// version1: 思路不够清晰准确,递推式写错但撞大运实现ok,可读性不好的初版
// 后追加注释
public class Solution {
    public int rob(int[] num) {
        if (num == null || num.length == 0) 
            return 0;
        int safe = 0; // num[i-2] 处能获取的最大盗金,num[i-2]本身不一定被盗
        int adj = 0; // num[i-1]能获取的最大盗金,num[i-1]本身不一定被盗
        int curr = 0; // 盗取num[i]所获的最大盗金
        int max = 0; // num[i]处能获取的最大盗金=max(curr, adj)
        for (int i = 0; i < num.length; i++) {
            curr = safe + num[i];
            if (curr > max)
                max = curr;
            safe = adj;
            adj = max;
        }
        return max;
    }
}
// version 2
// 递推式:safe[i] = max(safe[i-1], safe[i-2] + num[i])
// safe[2]表示num[i]处的最多盗金
// safe[1]表示num[i-1],即在与num[i]相邻的前面一户能拿的最大盗金
// safe[0]表示num[i-2]处最大盗金
public class Solution {
     public int rob(int[] num) {
        if (num == null || num.length == 0) 
            return 0;
        int n = num.length;
        if (n == 1)
            return num[0];
        else if (n == 2)
            return num[0] > num[1] ? num[0] : num[1];
        
        int[] safe = {num[0], (num[1] > num[0]? num[1] : num[0]), 0};
        for (int i = 2; i < num.length; i++) {
            safe[2] = Math.max(safe[1], safe[0] + num[i]);
            safe[0] = safe[1];
            safe[1] = safe[2];
        }
        return safe[2];
     }
}

    

 

 

分享到:
评论
4 楼 likesky3 2015-04-03  
赞yb君的代码精简,我会采纳你的意见,面试时可以先写safe[n]版,有时间再向面试官指出可以用更少的空间实现。当知道有更优化的方案时,我总想一次做到,完成时间自然会相应延迟些,我要有意识地培养first work than optimize的意识
3 楼 qb_2008 2015-04-02  
现在看起来好多了!如果想再优化,有一点代码可以去掉。
// 递推式:safe[i] = max(safe[i-1], safe[i-2] + num[i])  
// safe[2]表示num[i]处的最多盗金  
// safe[1]表示num[i-1],即在与num[i]相邻的前面一户能拿的最大盗金  
// safe[0]表示num[i-2]处最大盗金  
public class Solution {  
     public int rob(int[] num) {  
        if (num == null)   
            return 0;            
        int[] safe = {0, 0, 0};  // Does java initialize variables?: int[] safe = new int[3];
        for (int i = 0; i < num.length; i++) {  
            safe[2] = Math.max(safe[1], safe[0] + num[i]);  
            safe[0] = safe[1];  
            safe[1] = safe[2];  
        }  
        return safe[2];  
     }
}


另外,我感觉面试中更注重时间复杂度,对空间复杂度并不太注意,
所以我会选择直接用safe[n]的数组来递推,这样代码简单,正确性高,完成时间快。
// safe[i] is max amount of money we can rob from [0-i] houses.
// safe[i] = max(safe[i-1], safe[i-2] + num[i])   
public class Solution {  
     public int rob(int[] num) {  
        if (num == null || num.length == 0)   
            return 0;            
        else if (num.length == 1)
            return num[0];
        else if (num.length == 2)
            return Math.max(num[0], num[1]);

        int[] safe = new int[num.length];
        safe[0] = num[0];
        safe[1] = Math.max(safe[0], num[1]);
        for (int i = 2; i < num.length; i++) {
             safe[i] = Math.max(safe[i-1], safe[i-2] + num[i]);
        }  
        return safe[num.length - 1];  
     }
}
2 楼 likesky3 2015-04-02  
谢谢yb君的意见,我自己也觉得没描述清楚,而且递推式确实不准确,已更正
1 楼 qb_2008 2015-04-01  
safe[i]的定义为偷完前i户最大所得值。完整递推式应为safe[i] = max(safe[i - 1], safe[i - 2] + num[i])。
代码中把safe, adj, curr, max四个变量混在一起,着实难以理解。没有注释都看不懂,可不可以让可读性更好些?

相关推荐

    最大公共字符串leetcode-HouseRobber-Problem-LeetCode-:HouseRobber-问题-LeetCode-

    HouseRobber-问题-LeetCode- @Faizansayeed28 代码 /** * 问题陈述- 你是一名职业劫匪,计划抢劫街道上的房屋。 每个房子都有一定数量的钱 藏起来,阻止你抢劫他们的唯一限制是相邻的房子有安全系统 连接,如果同一...

    python-leetcode题解之213-House-Robber-II.py

    标题 "python-leetcode题解之213-House-Robber-II.py" 指明了文章的主体内容,即提供了一个Python语言编写的代码示例,用于解决LeetCode网站上的第213题——“打家劫舍 II”问题。这道题是“打家劫舍”系列问题的...

    c语言-leetcode题解之0337-house-robber-iii

    c c语言_leetcode题解之0337_house_robber_iii

    python-leetcode题解之198-House-Robber.py

    标题中提到的“python-leetcode题解之198-House-Robber.py”指的是一段用Python编写的针对LeetCode网站上编号为198的“打家劫舍”问题的解答代码。LeetCode是一个提供算法面试准备题库的平台,其中包含了大量的编程...

    LeetCode:Leetcode-解决方案

    House Robber [198]6. Range Sum Query - Immutable [303]7. Counting Bits [338]8. Palindromic Substrings [647]9. Maximum Length of Pair Chain [646]10. Integer Break [343]11. Count Numbers with Unique ...

    leetcode分类-leetcode:leetcode刷题(中等难度分类)

    2. 动态规划:"House Robber"(打家劫舍)系列问题,展示了动态规划在求解最优解方面的应用,通过状态转移方程可以求得最大收益。 3. 分治法:"Median of Two Sorted Arrays"(两个排序数组的中位数)是分治策略的...

    leetcode和oj-OJ_Solution:leetcode、poj等OJ解决方案

    leetcode 和 oj OJ_Solution Solutions for OJ such as leetcode, poj and so on 版本 ...https://leetcode.com/problems/two-sum/ ...java/houserobber https://leetcode.com/problems/house-robber/

    leetcode卡-leet-code-may-challenge:包含对MayChallenge(LeetCode)上发布的问题的解决方案。

    1. 动态规划:如“House Robber”问题,考察了如何用动态规划状态转移方程来求解最优决策。 2. 二叉树:例如“Lowest Common Ancestor of a Binary Tree”涉及到二叉树的遍历和节点查找。 3. 图论:如“Course ...

    python-leetcode面试题解之第198题打家劫舍-题解.zip

    本压缩包中的内容是针对LeetCode平台上的第198题“打家劫舍”(House Robber)的Python解决方案。 “打家劫舍”是一道经典的动态规划问题,其核心在于寻找最优策略,即在不触动相邻房屋的情况下,最大化抢劫的财富...

    javascript-leetcode面试题解动态规划问题之第198题打家劫舍-题解.zip

    本题解将深入探讨第198题“打家劫舍”(House Robber),这是一个典型的动态规划问题,对于理解该算法模式及其应用至关重要。 动态规划是一种解决最优化问题的方法,通过将大问题分解为更小的子问题来求解。在这个...

    lrucacheleetcode-LeetCode:复制和思考

    lru cache leetcode LeetCode copy and think 加油学习 1. 时间轴 时间 题目 描述 知识点 ...House Robber 动态规划 如何确定子问题 20200525 20200525 20200525 20200525 20200525 20200525 $1 234

    python-leetcode面试题解之第337题打家劫舍III.zip

    在LeetCode平台上,第337题“打家劫舍III”(House Robber III)是一道涉及深度优先搜索(DFS)和树结构的经典算法题。这道题目要求我们通过Python编程来解决一个树形结构下的抢劫问题,旨在考察我们对递归、树遍历...

    leetcode最大蓄水量-leetcode:记录自己leetocde的过程

    House Robber 学会了数组的创建,以及动态规划最基本的题目 2021.2.2 322 兑换钱币 学会了 Arrays.fill 的使用,以及查看源码,返回 记录在哔哩哔哩 中 2021.2.3 53 最大子数字之和 先更新max,再将负数赋值为0 62 ...

    gasstationleetcode-leetcode:LeetcodeOJ解决方案

    leetcode 【演示记录】 报告 展示 2017/03/06 1.二和,167.二和二 2107/03/06 15.3 总和,16.3 总和最近,18.4 总和,11.最多水的容器 2017/03/09 62.Unique Paths, 63.Unique Paths II, 64.Minimum Path Sum 2017/...

    lrucacheleetcode-LeetCode:CppSourceCode的LeetCode解决方案

    lru cache leetcode LeetCode 解决题目的总数: 136/1753 微信公众号: 工程师Ruojhen 算法-动态规划 题号 名称 English Name 题解 53 最大子序和 Maximum Subarray 70 ...House Robber 213 打家劫舍Ⅱ

    leetcode常见的100热点算法题

    例如,"Unique Paths"(不同路径)和"House Robber"(打家劫舍)都是经典的动态规划题目。 3. **回溯与深度优先搜索**:这类算法通常用于解决组合优化问题和图遍历问题。例如,"N-Queens"(八皇后问题)和"Word ...

    Leetcode部分试题解析

    18. **House Robber**:打劫问题。这是动态规划的应用,计算在不触动相邻房屋的情况下能偷窃的最大价值。 19. **Palindrome Linked List** 和 **Palindrome Number**:判断链表或数字是否为回文。链表可以用双指针...

    LeetCode判断字符串是否循环-data-structure-and-algo:C++中的数据结构和算法

    HouseRobber(#198), ClimbingStairs(#70), CoinChange(#322), EditDistance(#72) 图 : 集合的合并(直接求并、按大小求并和按深度求并)、根搜寻(路径压缩) : 有向图和无向图的邻接表表示方法 : 图的深度优先和广度...

    Roberry_house_dynamicprogramming_源码

    在这个场景中,"Roberry_house_dynamicprogramming_源码" 提到的是一个关于房屋盗窃问题的动态规划解决方案,通常被称为“House Robber”问题。这个问题源于LeetCode等在线编程挑战平台,旨在锻炼程序员的逻辑思维和...

    JAVA程序设计上机课4_阳甫军‘.pptx

    1. LeetCode 198:House Robber(打家劫舍) - 这是一个经典的动态规划问题,目标是确定在一个房子列表中,不相邻的房子可以被抢劫的最大金额。需要提交代码并附上运行结果截图。 2. LeetCode 349:Intersection ...

Global site tag (gtag.js) - Google Analytics