Leetcode: House Robber 系列
這個系列包括以下題目:
- 198. House Robber
- 213. House Robber II
- 337. House Robber III
198. House Robber
題目意思是:給出一系列數字,代表房子可以搶的錢,不能同時搶相鄰的房子的錢,問能搶到的最大值。
得到動態轉移方程如下:
dp[i] = max(dp[i-1],dp[i-2]+nums[i]);
now = max(pre,bef+nums[i]);
now=pre;
pre=bef;
這樣複雜度是O(n)+O(1)。
213. House Robber II
題目意思是:給出一系列數字,代表房子可以搶的錢,不能同時搶相鄰的房子的錢,問能搶到的最大值。多了一個限制條件,就是房子間是連成一個環的,意味這第一間房子和最後一間是相連的。
得到動態轉移方程如下:
dp[i] = max(dp[i-1],dp[i-2]+nums[i]);
now = max(pre,bef+nums[i]);
now=pre;
pre=bef;
這樣複雜度是O(n)+O(1)。
是的,思路和第一題一樣,不過就是要特殊解決環狀帶來的第一間房子和最後一間房子相鄰的問題。那麼就有:
now_1ton = max(now_1ton-1,now_2ton);
就是比較不搶劫1或者不搶劫n兩種情況(都不搶的情況如果是解,肯定是會包含在這兩個情況裏面的)。然後就done啦。
Leetcode: House Robber 系列
這個系列包括以下題目:
- 198. House Robber
- 213. House Robber II
- 337. House Robber III
198. House Robber
題目意思是:給出一系列數字,代表房子可以搶的錢,不能同時搶相鄰的房子的錢,問能搶到的最大值。
得到動態轉移方程如下:
dp[i] = max(dp[i-1],dp[i-2]+nums[i]);
now = max(pre,bef+nums[i]);
now=pre;
pre=bef;
這樣複雜度是O(n)+O(1)。
337. House Robber III
題目意思是:給出一系列數字,代表房子可以搶的錢,不能同時搶相鄰的房子的錢,問能搶到的最大值。這次的附加條件是,房子間的相鄰關係可以表示爲一顆二叉樹。
這個比較複雜,肯定就是要用dp的了。現在要考慮的是要怎麼分解爲子問題。首先,
dp_root = max(dp_left,dp_right);
類似這樣是不行的,因爲你不知道到底有沒有選了left或者right,只要選了一個,你就不能選root,但要是都不選,root又可以選。所以考慮跨一級。考慮孫子ll,lr,rl,rr四個孫子。考慮兩種情況,選root(root->val + dp_ll + dp_lr + dp_rl + dp_rr)或者不選root(dp_l + dp_r)。
得到動態轉移方程如下:
dp_root = max(root->val + dp_ll + dp_lr + dp_rl + dp_rr, dp_l + dp_r));
代碼
class Solution {
public:
int tryRob(TreeNode* root, int& l, int& r) {
if (!root)
return 0;
int ll = 0, lr = 0, rl = 0, rr = 0;
l = tryRob(root->left, ll, lr);
r = tryRob(root->right, rl, rr);
return max(root->val + ll + lr + rl + rr, l + r);
}
int rob(TreeNode* root) {
int l, r;
return tryRob(root, l, r);
}
};
這樣複雜度是O(n)。