vault backup: 2022-07-20 22:44:44
This commit is contained in:
parent
04d36288ad
commit
4727c3321a
147
OJ notes/pages/Leetcode House-Robber.md
Normal file
147
OJ notes/pages/Leetcode House-Robber.md
Normal file
|
@ -0,0 +1,147 @@
|
|||
# Leetcode House-Robber
|
||||
|
||||
#### 2022-07-20 22:21
|
||||
|
||||
> ##### Algorithms:
|
||||
> #algorithm #dynamic_programming
|
||||
> ##### Difficulty:
|
||||
> #coding_problem #difficulty-medium
|
||||
> ##### Additional tags:
|
||||
> #leetcode
|
||||
> ##### Revisions:
|
||||
> N/A
|
||||
|
||||
##### Related topics:
|
||||
```expander
|
||||
tag:#dynamic_programming
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### Links:
|
||||
- [Link to problem](https://leetcode.com/problems/house-robber/)
|
||||
- [Tutorial and explanation on DP](https://leetcode.com/problems/house-robber/discuss/156523/From-good-to-great.-How-to-approach-most-of-DP-problems.)
|
||||
___
|
||||
### Problem
|
||||
|
||||
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 systems connected and **it will automatically contact the police if two adjacent houses were broken into on the same night**.
|
||||
|
||||
Given an integer array `nums` representing the amount of money of each house, return _the maximum amount of money you can rob tonight **without alerting the police**_.
|
||||
|
||||
#### Examples
|
||||
|
||||
**Example 1:**
|
||||
|
||||
```markdown
|
||||
**Input:** nums = [1,2,3,1]
|
||||
**Output:** 4
|
||||
**Explanation:** Rob house 1 (money = 1) and then rob house 3 (money = 3).
|
||||
Total amount you can rob = 1 + 3 = 4.
|
||||
```
|
||||
|
||||
**Example 2:**
|
||||
|
||||
```markdown
|
||||
**Input:** nums = [2,7,9,3,1]
|
||||
**Output:** 12
|
||||
**Explanation:** Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1).
|
||||
Total amount you can rob = 2 + 9 + 1 = 12.
|
||||
```
|
||||
|
||||
#### Constraints
|
||||
|
||||
- `1 <= nums.length <= 100`
|
||||
- `0 <= nums[i] <= 400`
|
||||
|
||||
### Thoughts
|
||||
|
||||
> [!summary]
|
||||
> This is a #dynamic_programming problem.
|
||||
|
||||
According to [This tuturial](https://leetcode.com/problems/house-robber/discuss/156523/From-good-to-great.-How-to-approach-most-of-DP-problems.), the code can be derived from 3 stages:
|
||||
|
||||
#### Stage 1: Find recursive (unoptimized) solution
|
||||
|
||||
The robbing problem can be simplified as follows:
|
||||
|
||||
> Whether to rob or not?
|
||||
> - if rob, profit = nums[n] + rob(nums, n - 2)
|
||||
> - else, profit = rob(nums, n - 1)
|
||||
|
||||
The recursive solution can be represented as follows:
|
||||
|
||||
##### Base case: nums.size() = 0 || 1 || 2
|
||||
|
||||
##### Pseudo code:
|
||||
|
||||
- check for base case
|
||||
- return max(robbery(nums, n - 1), robbery(nums, n - 2) + nums[n])
|
||||
|
||||
#### Stage 2: Find recursive solution with cache
|
||||
|
||||
Since the core of DP as about re-using answers from before, we can cache the answers to make the code faster.
|
||||
|
||||
##### Pseudo code:
|
||||
|
||||
- Check for base case
|
||||
- if cache found, return
|
||||
- assign the computed value to cache
|
||||
- return the cached value
|
||||
|
||||
#### Stage 3: Find iterative solution with caching
|
||||
|
||||
By using iterative, we can use less memory than recursion (return stack).
|
||||
|
||||
We start from bottom to top, rather than from top to down, and use the cached answer to proceed to the final answer
|
||||
|
||||
#### Stage 4: Optimize it by using variables rather than hash table based caching
|
||||
|
||||
This can be different from problem to problem, but for this case,
|
||||
we achieve constant space complexity using variables.
|
||||
|
||||
### Solution
|
||||
|
||||
#### Stage 1:
|
||||
|
||||
TLE, I didn't save this one
|
||||
|
||||
#### Stage 2:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
vector<int> cache;
|
||||
int robbery(vector<int> &nums, int nextLoc) {
|
||||
// base cases:
|
||||
// nextLoc == 0, return nums[1]
|
||||
// nextLoc == 1, return nums[2]
|
||||
if (nextLoc < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cache[nextLoc] != -1) {
|
||||
return cache[nextLoc];
|
||||
}
|
||||
|
||||
cache[nextLoc] = max(robbery(nums, nextLoc - 1),
|
||||
robbery(nums, nextLoc - 2) + nums[nextLoc]);
|
||||
|
||||
return cache[nextLoc];
|
||||
}
|
||||
|
||||
public:
|
||||
int rob(vector<int> &nums) {
|
||||
// Version one
|
||||
// Recursion
|
||||
// rob current store: nums[i] + rob(i - 2)
|
||||
// don't rob current home: rob(i - 1)
|
||||
cache = vector<int>(nums.size(), -1);
|
||||
|
||||
return robbery(nums, nums.size() - 1);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
#### Stage 3:
|
||||
|
||||
```cpp
|
||||
|
Loading…
Reference in a new issue