针对Byte Dance某一次面试的算法题目(LC 337. 打家劫舍 III ),现做如下整理。
目录
声明:以下“选”和“劫取”是同义词,自由替换
LC 198. 打家劫舍
思路
对于每一所房子有两种状态,要么选择,要么不选择,使用dp[i]记录当前位置房子所能劫取到的最大价值,即有:dp[i] = max(dp[i - 1], dp[i - 2] + nums[i])
代码
const int N = 105;
class Solution {
public:
int dp[N];
int rob(vector<int>& nums) {
int n = nums.size();
if (n == 0) return 0;
if (n == 1) return nums[0];
dp[0] = nums[0];
dp[1] = max(dp[0], nums[1]); // 两种选择,要么劫取1,2不劫取;要么劫取2,1不劫取
for (int i = 2; i < n; i ++ ) dp[i] = max(dp[i - 1], dp[i - 2] + nums[i]);
return dp[n - 1];
}
};
LC 213. 打家劫舍 II
思路
将问题划得分:
- 第一座房子选择偷,那么最后一座房子一定不能偷,此时计算0 ~ n - 2,由dp[n - 2]得到当前方案最大值
- 第一座房子不偷,最后一座房子可偷可不偷(反正可以偷,那就计算上),此时计算1 ~ n - 1,由dp[n - 1]取得当前方案最大值
递推式和打家劫舍I的一致,最后两种方案各自最优情况取最大值即可。
代码
const int N = 105;
class Solution {
public:
int dp[N];
int rob(vector<int>& a) {
int n = a.size();
// 情况特判
if (n == 1) return a[0];
else if (n == 2) return max(a[0], a[1]);
dp[0] = a[0]; // 第一家要偷,最后一家不能偷:0~n-2
dp[1] = max(dp[0], a[1]);
for (int i = 2; i < n - 1; i ++ ) dp[i] = max(dp[i - 2] + a[i], dp[i - 1]);
int ans = dp[n - 2];
dp[0] = 0; // 第一家不偷,最后一家看情况:0~n-1
dp[1] = a[1];
dp[2] = max(a[2], dp[1]);
for (int i = 3; i < n; i ++ ) dp[i] = max(dp[i - 2] + a[i], dp[i - 1]);
ans = max(dp[n - 1], ans);
return ans;
}
};
LC 337. 打家劫舍 III
思路
针对某个节点(将其视为root考虑),若选择了该节点那么f[root, 1] = f[left, 0] + f[right, 1] + nums[i](其中0代表不选,1代表选);若不选该节点那么f[root, 0] = max(f[left, 0], f[right, 1]) + max(f[right, 0], f[left, 1])
代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> dfs(TreeNode* u) {
if (!u) return {0, 0};
vector<int> x = dfs(u->left), y = dfs(u->right);
return {max(x[0], x[1]) + max(y[0], y[1]), x[0] + y[0] + u->val};
}
int rob(TreeNode* root) {
if (!root) return 0;
vector<int> f = dfs(root);
return max(f[0], f[1]);
}
};