打家劫舍问题总结
首先声明一点,我不一定会选择最优的解法,但是我一定会选择最容易理解的做法
- 事实上,在dp问题的优化上,我们也只能够优化空间复杂度,即dp问题的时间复杂度是固定的
- 而且一般最优解法比较难想,所以我们先从最容易理解的做法开始
LeetCode 198、打家劫舍 https://leetcode-cn.com/problems/house-robber/
- 当我们看到这个题目的时候,首先可以看出这是一个0-1背包问题,即我们只用考虑选不选择最后一个房屋即可.
- 那么状态转移方程可以很容易的写出来 dp[i]=max{dp[i-1],dp[i-2]+nums[i]}
1 | class Solution { |
LeetCode 213、打家劫舍2 https://leetcode-cn.com/problems/house-robber-ii/
- 此问题与第一版不同,此时是一个环,而不是一条直线,这就意味着我们在选择第一家时,就不能选择最后一家。
- 同理,我们如果选择了最后一家,那么就不能选择最后一家。
- 那么我们可以分两种情况,这时就有一个有趣的地方,以往我们在做dp问题时都是一个dp数组,一维或者二维,现在这里我们可以分为两个dp数组,比较直观
1 | class Solution { |
- 我们可以看出,上题还是有很多细节的,如果有些地方稍微写错,那么就跑不出我们想要的答案.
接下来我们来到最后一个问题
LeetCode 337、打家劫舍3 https://leetcode-cn.com/problems/house-robber-iii/
- 这题也很有意思,让强盗在一棵二叉树上进行打劫,并且不能选择两个相邻的节点,这里的相邻是指他们之间有连接.
- 这里运用到了一个比较巧妙的思想,直接看代码
1 | class Solution { |
- 在这里我们非常巧妙的运用了递归,事实上,与树的很多问题我们都可以用递归来解决,在利用递归时,我们不必去考虑实现的细节,在本题中,我们不必去考虑左右子树的遍历过程。而只用考虑是否选择根节点即可
从打家劫舍1-3题,我们实现了从数组->环->树的 进阶。
本篇中我所提供的代码不一定是最优解,但是一定是最容易理解的解!