当前位置:   article > 正文

代码随想录算法训练营Day46 | 139.单词拆分,关于多重背包,你该了解这些!背包问题总结篇! | Day 17 & 18 复习

代码随想录算法训练营Day46 | 139.单词拆分,关于多重背包,你该了解这些!背包问题总结篇! | Day 17 & 18 复习

139.单词拆分

文章链接  |  题目链接  |  视频链接

C++解法

  1. class Solution {
  2. public:
  3. bool wordBreak(string s, vector<string>& wordDict) {
  4. unordered_set<string> wordSet(wordDict.begin(), wordDict.end());
  5. vector<bool> dp(s.size()+1, false);
  6. dp[0] = true;
  7. for (int i = 1; i <= s.size(); i++){
  8. for (int j = 0; j < i; j++){
  9. string word = s.substr(j, i-j);
  10. if (wordSet.find(word) != wordSet.end() && dp[j] == true){
  11. dp[i] = true;
  12. }
  13. }
  14. }
  15. return dp[s.size()];
  16. }
  17. };

Python解法

  1. class Solution:
  2. def wordBreak(self, s: str, wordDict: List[str]) -> bool:
  3. wordSet = set(wordDict)
  4. n = len(s)
  5. dp = [False] * (n + 1)
  6. dp[0] = True
  7. for i in range(1, n + 1):
  8. for j in range(i):
  9. if dp[j] and s[j:i] in wordSet:
  10. dp[i] = True
  11. break
  12. return dp[n]

关于多重背包,你该了解这些!

文章链接

有N种物品和一个容量为V 的背包。第i种物品最多有Mi件可用,每件耗费的空间是Ci ,价值是Wi 。求解将哪些物品装入背包可使这些物品的耗费的空间 总和不超过背包容量,且价值总和最大。

多重背包和01背包是非常像的, 为什么和01背包像呢?

每件物品最多有Mi件可用,把Mi件摊开,其实就是一个01背包问题了。

  1. void test_multi_pack() {
  2. vector<int> weight = {1, 3, 4};
  3. vector<int> value = {15, 20, 30};
  4. vector<int> nums = {2, 3, 2};
  5. int bagWeight = 10;
  6. for (int i = 0; i < nums.size(); i++) {
  7. while (nums[i] > 1) { // nums[i]保留到1,把其他物品都展开
  8. weight.push_back(weight[i]);
  9. value.push_back(value[i]);
  10. nums[i]--;
  11. }
  12. }
  13. vector<int> dp(bagWeight + 1, 0);
  14. for(int i = 0; i < weight.size(); i++) { // 遍历物品
  15. for(int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量
  16. dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
  17. }
  18. for (int j = 0; j <= bagWeight; j++) {
  19. cout << dp[j] << " ";
  20. }
  21. cout << endl;
  22. }
  23. cout << dp[bagWeight] << endl;
  24. }
  25. int main() {
  26. test_multi_pack();
  27. }

背包问题总结篇! 

文章链接

背包五部曲:

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

背包递推公式

问能否能装满背包(或者最多装多少):dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]); ,对应题目如下:

问装满背包有几种方法:dp[j] += dp[j - nums[i]] ,对应题目如下:

问背包装满最大价值:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]); ,对应题目如下:

问装满背包所有物品的最小个数:dp[j] = min(dp[j - coins[i]] + 1, dp[j]); ,对应题目如下:

如果求组合数就是外层for循环遍历物品,内层for遍历背包

如果求排列数就是外层for遍历背包,内层for循环遍历物品

01背包

二维dp数组01背包先遍历物品还是先遍历背包都是可以的,且第二层for循环是从小到大遍历。

一维dp数组01背包只能先遍历物品再遍历背包容量,且第二层for循环是从大到小遍历。

完全背包

如果求组合数就是外层for循环遍历物品,内层for遍历背包

如果求排列数就是外层for遍历背包,内层for循环遍历物品

相关题目如下:

如果求最小数,那么两层for循环的先后顺序就无所谓了,相关题目如下:

Day 17 复习

110.平衡二叉树 

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode() : val(0), left(nullptr), right(nullptr) {}
  8. * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  9. * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  10. * };
  11. */
  12. class Solution {
  13. public:
  14. bool isBalanced(TreeNode* root) {
  15. if (root == NULL) return true;
  16. unordered_map<TreeNode*, int> height_map;
  17. stack<TreeNode*> st;
  18. st.push(root);
  19. while (!st.empty()){
  20. TreeNode* curr = st.top();
  21. st.pop();
  22. if (curr != NULL){
  23. st.push(curr);
  24. st.push(NULL);
  25. if (curr->left){
  26. st.push(curr->left);
  27. }
  28. if (curr->right){
  29. st.push(curr->right);
  30. }
  31. } else {
  32. TreeNode* node = st.top();
  33. st.pop();
  34. int left = 0, right = 0;
  35. if (height_map.find(node->left) != height_map.end()){
  36. left = height_map[node->left];
  37. }
  38. if (height_map.find(node->right) != height_map.end()){
  39. right = height_map[node->right];
  40. }
  41. if (abs(left - right) > 1){
  42. return false;
  43. } else {
  44. height_map[node] = 1 + max(left, right);
  45. }
  46. }
  47. }
  48. return true;
  49. }
  50. };
  1. class Solution {
  2. public:
  3. int getHeight(TreeNode* node) {
  4. if (node == NULL) {
  5. return 0;
  6. }
  7. int leftHeight = getHeight(node->left);
  8. if (leftHeight == -1) return -1;
  9. int rightHeight = getHeight(node->right);
  10. if (rightHeight == -1) return -1;
  11. return abs(leftHeight - rightHeight) > 1 ? -1 : 1 + max(leftHeight, rightHeight);
  12. }
  13. bool isBalanced(TreeNode* root) {
  14. return getHeight(root) == -1 ? false : true;
  15. }
  16. };

257. 二叉树的所有路径

 

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode() : val(0), left(nullptr), right(nullptr) {}
  8. * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  9. * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  10. * };
  11. */
  12. class Solution {
  13. public:
  14. void traverse(TreeNode* curr, vector<string>& result, string path){
  15. if (curr == NULL){
  16. return;
  17. }
  18. path = path + to_string(curr->val);
  19. if (curr->left == NULL && curr->right == NULL){
  20. result.push_back(path);
  21. return;
  22. }
  23. if (curr->left){
  24. path = path + "->";
  25. traverse(curr->left, result, path);
  26. path.pop_back();
  27. path.pop_back();
  28. }
  29. if (curr->right){
  30. path = path + "->";
  31. traverse(curr->right, result, path);
  32. path.pop_back();
  33. path.pop_back();
  34. }
  35. }
  36. vector<string> binaryTreePaths(TreeNode* root) {
  37. vector<string> result;
  38. traverse(root, result, "");
  39. return result;
  40. }
  41. };

404.左叶子之和 

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode() : val(0), left(nullptr), right(nullptr) {}
  8. * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  9. * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  10. * };
  11. */
  12. class Solution {
  13. public:
  14. int sumOfLeftLeaves(TreeNode* root) {
  15. if (root == NULL) return 0;
  16. if (root->left == NULL && root->right == NULL) return 0;
  17. int left = 0;
  18. if (root->left && root->left->left == NULL && root->left->right == NULL){
  19. left = root->left->val;
  20. }
  21. return left + sumOfLeftLeaves(root->left) + sumOfLeftLeaves(root->right);
  22. }
  23. };

Day 18 复习

513.找树左下角的值

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode() : val(0), left(nullptr), right(nullptr) {}
  8. * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  9. * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  10. * };
  11. */
  12. class Solution {
  13. public:
  14. int max_depth = INT_MIN;
  15. int left_most_val = -1;
  16. void traverse(TreeNode* curr, int level){
  17. if (curr == NULL){
  18. return;
  19. }
  20. if (curr->left == NULL && curr->right == NULL){
  21. if (level > max_depth){
  22. left_most_val = curr->val;
  23. max_depth = level;
  24. return;
  25. }
  26. }
  27. traverse(curr->left, level+1);
  28. traverse(curr->right, level+1);
  29. }
  30. int findBottomLeftValue(TreeNode* root) {
  31. traverse(root, 0);
  32. return left_most_val;
  33. }
  34. };

112. 路径总和

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode() : val(0), left(nullptr), right(nullptr) {}
  8. * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  9. * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  10. * };
  11. */
  12. class Solution {
  13. public:
  14. bool hasPathSum(TreeNode* root, int targetSum) {
  15. if (root == NULL) return false;
  16. if (root->left == NULL && root->right == NULL && targetSum == root->val){
  17. return true;
  18. }
  19. targetSum -= root->val;
  20. return hasPathSum(root->left, targetSum) or hasPathSum(root->right, targetSum);
  21. }
  22. };

113.路径总和ii

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode() : val(0), left(nullptr), right(nullptr) {}
  8. * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  9. * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  10. * };
  11. */
  12. class Solution {
  13. public:
  14. void traverse(TreeNode* curr, int targetSum, vector<int> path, vector<vector<int>>& result){
  15. if (curr == NULL){
  16. return;
  17. }
  18. if (curr->left == NULL && curr->right == NULL && targetSum == curr->val){
  19. path.push_back(curr->val);
  20. result.push_back(path);
  21. return;
  22. }
  23. targetSum -= curr->val;
  24. path.push_back(curr->val);
  25. traverse(curr->left, targetSum, path, result);
  26. traverse(curr->right, targetSum, path, result);
  27. }
  28. vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
  29. vector<vector<int>> result;
  30. vector<int> path;
  31. traverse(root, targetSum, path, result);
  32. return result;
  33. }
  34. };

106.从中序与后序遍历序列构造二叉树

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode() : val(0), left(nullptr), right(nullptr) {}
  8. * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  9. * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  10. * };
  11. */
  12. class Solution {
  13. public:
  14. TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
  15. if (inorder.size() < 1 || postorder.size() < 1){
  16. return NULL;
  17. }
  18. return traverse(inorder, postorder);
  19. }
  20. private:
  21. TreeNode* traverse(vector<int>& inorder, vector<int>& postorder){
  22. if (postorder.size() == 0){
  23. return NULL;
  24. }
  25. int root_val = postorder[postorder.size() - 1];
  26. TreeNode *root = new TreeNode(root_val);
  27. if (postorder.size() == 1) return root;
  28. int index = 0;
  29. for (int i = 0; i < inorder.size(); i++){
  30. if (inorder[i] == root_val){
  31. index = i;
  32. break;
  33. }
  34. }
  35. vector<int> inorder_left(inorder.begin(), inorder.begin() + index);
  36. vector<int> inorder_right(inorder.begin() + index + 1, inorder.end());
  37. vector<int> postorder_left(postorder.begin(), postorder.begin() + inorder_left.size());
  38. vector<int> postorder_right(postorder.begin() + inorder_left.size(), postorder.end() - 1);
  39. root->left = traverse(inorder_left, postorder_left);
  40. root->right = traverse(inorder_right, postorder_right);
  41. return root;
  42. }
  43. };

105.从前序与中序遍历序列构造二叉树

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode() : val(0), left(nullptr), right(nullptr) {}
  8. * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  9. * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  10. * };
  11. */
  12. class Solution {
  13. public:
  14. TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
  15. if (preorder.size() < 1) return NULL;
  16. int root_val = preorder[0];
  17. TreeNode* root = new TreeNode(root_val);
  18. int index = 0;
  19. for (int i = 0; i < inorder.size(); i++){
  20. if (inorder[i] == root_val){
  21. index = i;
  22. break;
  23. }
  24. }
  25. vector<int> inorder_left(inorder.begin(), inorder.begin()+index);
  26. vector<int> inorder_right(inorder.begin()+index+1, inorder.end());
  27. vector<int> preorder_left(preorder.begin()+1, preorder.begin()+inorder_left.size() + 1);
  28. vector<int> preorder_right(preorder.begin()+inorder_left.size()+1, preorder.end());
  29. root->left = buildTree(preorder_left, inorder_left);
  30. root->right = buildTree(preorder_right, inorder_right);
  31. return root;
  32. }
  33. };
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/214819
推荐阅读