1--打家劫舍III
主要思路:
基于从下到上的 dp 回溯法,每一个节点只有两种状态,dp[0]表示被打劫,dp[1]表示不被打劫;
当前节点被打劫时,其孩子只能都不被打劫;dp[0] = left[1] + right[1] + cur->val;
当前节点不被打劫时,其孩子可以都被打劫,也可以都不被打劫,或者一个被打劫另一个不被打劫。
dp[1] = max(left[0] + right[0], left[1] + right[1], left[0] + right[1], left[1] + right[0]);
#include <iostream>
#include <vector>
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:
int rob(TreeNode* root) {
// 对于每一间房屋,有被打劫和不被打劫两种状态
std::vector<int> res = dfs(root);
return std::max(res[0], res[1]);
}
std::vector<int> dfs(TreeNode* cur){
if(cur == nullptr) return {0, 0};
std::vector<int> left = dfs(cur->left);
std::vector<int> right = dfs(cur->right);
std::vector<int> dp(2, 0); // dp[0]表示被打劫 dp[1]表示不被打劫
dp[0] = left[1] + right[1] + cur->val; // 当前房屋被打劫,其孩子只能不被打劫
// 当前房屋不被打劫,其孩子可以同时被打劫,也可以同时不被打劫
// 当前房屋不被打劫,其孩子可以一个被打劫,另一个不被打劫
dp[1] = std::max(std::max(std::max(left[0] + right[0], left[1] + right[1]), left[0] + right[1]), left[1] + right[0]);
return dp;
}
};
int main(int argc, char* argv[]){
// root = [3, 2, 3, null, 3, null, 1]
TreeNode *Node1 = new TreeNode(3);
TreeNode *Node2 = new TreeNode(2);
TreeNode *Node3 = new TreeNode(3);
TreeNode *Node4 = new TreeNode(3);
TreeNode *Node5 = new TreeNode(1);
Node1->left = Node2;
Node1->right = Node3;
Node2->right = Node4;
Node3->right = Node5;
Solution S1;
int res = S1.rob(Node1);
std::cout << res << std::endl;
return 0;
}
2--比特位计数
主要思路:
#include <iostream>
#include <vector>
class Solution {
public:
std::vector<int> countBits(int n) {
std::vector<int> dp(n + 1, 0);
int high_valid = 0;
for(int i = 1; i <= n; i++){
if((i & (i - 1)) == 0){ // i是2的指数幂,更新最高有效位
high_valid = i;
}
dp[i] = dp[i - high_valid] + 1;
}
return dp;
}
};
int main(int argc, char* argv[]){
// n = 5
int n = 5;
Solution S1;
std::vector<int> res = S1.countBits(n);
for(auto num : res)
std::cout << num << " ";
std::cout << std::endl;
return 0;
}