LeetCode Hot 100 No.198 打家劫舍

本文解析了一个关于小偷避开防盗系统的动态规划问题,通过分析如何在一夜之间最大化偷窃金额而不触发报警,展示了从数组中计算最优路径的方法。核心思路是利用steal和notsteal数组来保存每一步的决策结果,并在遍历过程中更新最大收益。

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

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

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

思路:
这道题是动态规划问题。
1,2,3,1
例如这四个房子。我们从前往后依次遍历,每当我们到达一个房子的时候,我们都会有两种选择,
第一种就是偷它,但是我就不能偷它左边的房子了。
第二种就是我不偷这个房子,但是我可以偷它左边的房子。
我们用两个数组来保存偷每个房子和不偷每个房子所能得到的总钱数。
int[] steal;
int[] notsteal;
1.对于第一个房子1,steal [0]=1. notsteal [0] = 0.这很好理解,因为它之前没有房子,偷这个房子,能得到的钱数就是1,不偷这个房子能得到的钱数就是0.
2.对于第二个房子2, steal [1] = 2+ notsteal [0] .这也很好理解,因为如果偷了2, 那就不能偷 1. 同样的 notsteal [1] = max( steal [0] + notsteal [0]). 这里需要注意,当我不偷2的时候,我既可以偷1 ,也可以不偷1 ,所以当我不偷2时所能得到的总钱数为偷1 和不偷1 的最大值。
3.对于第三个房子3 ,同理, steal [2] = 3+ notsteal [1], notsteal [2] = max( steal [1] + notsteal [1]).
依次类推。。。
当我们遍历到最后一个房子的时候,我们也可以获得偷它和不偷它的总钱数。那么我们偷这所有的房子所能获得的总钱数就是这两个钱数的最大值。
我们可以写出递推公式:
steal [ i ] = nums [ i ] + notsteal [ i-1 ]
notsteal [ i ] = max ( steal [ i-1] , notsteal [ i-1 ] )

本质上就是从后往前的递归,但是这种递归就可以转化为从前往后的形式,这种形式就叫动态规划
我们进一步优化,每次循环我们只要知道 steal [ i-1] 和 notsteal [ i-1 ] 就行了,所以我们就用两个变量来保存上一次循环的结果就可以,不需要再用两个数组保存。

class Solution {
    public int rob(int[] nums) {
        int Stealme = nums[0];
        int notStealme = 0;
        for(int i=1;i<nums.length;i++)
        {
            int lastStealme = Stealme;
            int lastnotStealme = notStealme;
            Stealme = nums[i]+ lastnotStealme;
            notStealme = Math.max(lastStealme,lastnotStealme);
        }
        return Math.max(Stealme,notStealme);

    }
}
### LeetCode Hot 100 Problems 列表 LeetCode 的热门题目列表通常由社区投票选出,涵盖了各种难度级别的经典编程挑战。这些题目对于准备技术面试非常有帮助。以下是部分 LeetCode 热门 100 题目列表: #### 数组与字符串 1. **两数之和 (Two Sum)** 2. **三数之和 (3Sum)** 3. **无重复字符的最长子串 (Longest Substring Without Repeating Characters)** 4. **寻找两个正序数组的中位数 (Median of Two Sorted Arrays)** #### 动态规划 5. **爬楼梯 (Climbing Stairs)** 6. **不同的二叉搜索树 (Unique Binary Search Trees)** 7. **最大子序列和 (Maximum Subarray)** #### 字符串处理 8. **有效的括号 (Valid Parentheses)** 9. **最小覆盖子串 (Minimum Window Substring)** 10. **字母异位词分组 (Group Anagrams)** #### 图论 11. **岛屿数量 (Number of Islands)** 12. **课程表 II (Course Schedule II)** #### 排序与查找 13. **最接近原点的 K 个点 (K Closest Points to Origin)** 14. **接雨水 (Trapping Rain Water)** 15. **最长连续序列 (Longest Consecutive Sequence)[^2]** #### 堆栈与队列 16. **每日温度 (Daily Temperatures)** 17. **滑动窗口最大值 (Sliding Window Maximum)** #### 树结构 18. **验证二叉搜索树 (Validate Binary Search Tree)** 19. **二叉树的最大路径和 (Binary Tree Maximum Path Sum)** 20. **从前序与中序遍历序列构造二叉树 (Construct Binary Tree from Preorder and Inorder Traversal)** #### 并查集 21. **冗余连接 II (Redundant Connection II)** #### 贪心算法 22. **跳跃游戏 (Jump Game)** 23. **分割等和子集 (Partition Equal Subset Sum)** #### 双指针技巧 24. **环形链表 II (Linked List Cycle II)[^1]** 25. **相交链表 (Intersection of Two Linked Lists)** #### 其他重要题目 26. **LRU缓存机制 (LRU Cache)** 27. **打家劫舍系列 (House Robber I & II)** 28. **编辑距离 (Edit Distance)** 29. **单词拆分 (Word Break)** 此列表并非官方发布版本而是基于社区反馈整理而成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值