当前位置:   article > 正文

DFS:深搜+回溯+剪枝解决组合问题

DFS:深搜+回溯+剪枝解决组合问题

                                               创作不易,感谢支持!!!

一、电话号码的组合

. - 力扣(LeetCode)

  1. class Solution {
  2. public:
  3. string hash[10]={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
  4. string path;//记录路径
  5. vector<string> ret;//记录返回值
  6. vector<string> letterCombinations(string digits)
  7. {
  8. if(digits.size()==0) return ret;
  9. dfs(digits,0);
  10. return ret;
  11. }
  12. void dfs(string &digits,int pos)
  13. {
  14. if(path.size()==digits.size()) {ret.push_back(path);return;}
  15. for(auto ch:hash[digits[pos]-'0'])//从当前位置开始遍历,然后再去下一个里面找
  16. {
  17. path.push_back(ch);
  18. dfs(digits,pos+1);
  19. path.pop_back();
  20. }
  21. }
  22. };

二、括号生成

. - 力扣(LeetCode)

  1. class Solution {
  2. public:
  3. vector<string> ret;
  4. string path;
  5. int n;
  6. vector<string> generateParenthesis(int _n)
  7. {
  8. n=_n;
  9. dfs(0,0);
  10. return ret;
  11. }
  12. void dfs(int open,int close)//open和close记录上界和下界
  13. {
  14. if(path.size()==2*n) {ret.push_back(path);return;}
  15. if(open<n)
  16. {
  17. path.push_back('(');
  18. dfs(open+1,close);
  19. path.pop_back();
  20. }
  21. if(close<open)
  22. {
  23. path.push_back(')');
  24. dfs(open,close+1);
  25. path.pop_back();
  26. }
  27. }
  28. };

 三、组合

. - 力扣(LeetCode)

  1. class Solution {
  2. public:
  3. vector<vector<int>> ret;
  4. vector<int> path;
  5. int k;//用k全局,可以减少一个参数
  6. int n;//用n全局,可以减少一个参数
  7. vector<vector<int>> combine(int _n, int _k)
  8. {
  9. k=_k;
  10. n=_n;
  11. dfs(1);
  12. return ret;
  13. }
  14. void dfs(int pos)
  15. {
  16. if(path.size()==k) {ret.push_back(path);return;}
  17. for(int i=pos;i<=n;++i)
  18. {
  19. path.push_back(i);
  20. dfs(i+1);
  21. path.pop_back();
  22. }
  23. }
  24. };

四、目标和

. - 力扣(LeetCode)

  1. class Solution {
  2. int ret=0;//记录返回结果
  3. public:
  4. int findTargetSumWays(vector<int>& nums, int target)
  5. {
  6. dfs(nums,target,0,0);
  7. return ret;
  8. }
  9. void dfs(vector<int>& nums, int target,int index,int sum)
  10. {
  11. if(index==nums.size())
  12. {
  13. if(sum==target) ++ret;
  14. }
  15. //选正数
  16. else
  17. {
  18. dfs(nums,target,index+1,sum+nums[index]);
  19. dfs(nums,target,index+1,sum-nums[index]);
  20. }
  21. }
  22. };

五、组合总和I

. - 力扣(LeetCode)

  1. class Solution {
  2. vector<vector<int>> ret;
  3. vector<int> path;
  4. public:
  5. vector<vector<int>> combinationSum(vector<int>& candidates, int target)
  6. {
  7. dfs(candidates,0,target);
  8. return ret;
  9. }
  10. void dfs(vector<int>& candidates,int pos,int target)
  11. {
  12. if(target==0){ ret.push_back(path);return;}
  13. if(target<0) return;
  14. for(int i=pos;i<candidates.size();++i)//第一层,遍历每个数
  15. {
  16. path.push_back(candidates[i]);
  17. dfs(candidates,i,target-candidates[i]);//要从原先的位置去找
  18. path.pop_back();
  19. }
  20. }
  21. };

  1. class Solution {
  2. vector<vector<int>> ret;
  3. vector<int> path;
  4. public:
  5. vector<vector<int>> combinationSum(vector<int>& candidates, int target)
  6. {
  7. dfs(candidates,0,target);
  8. return ret;
  9. }
  10. void dfs(vector<int>& nums,int pos,int target)
  11. {
  12. if(target==0){ ret.push_back(path);return;}
  13. if(target<0||pos==nums.size()) return;
  14. for(int k=0;k*nums[pos]<=target;++k)//第一层,遍历每个数
  15. {
  16. if(k) path.push_back(nums[pos]);
  17. dfs(nums,pos+1,target-k*nums[pos]);//要从原先的位置去找
  18. }
  19. for(int k=1;k*nums[pos]<=target;++k) path.pop_back();//
  20. }
  21. };

六、组合总和II

. - 力扣(LeetCode)

七、组合总和III

. - 力扣(LeetCode)

  1. class Solution {
  2. public:
  3. vector<vector<int>> ret;//记录组合
  4. vector<int> path;//记录路径
  5. vector<vector<int>> combinationSum3(int k, int n) {
  6. if(n>45) return ret;//剪枝
  7. dfs(k,n,1);
  8. return ret;
  9. }
  10. void dfs(int k,int n,int pos)
  11. {
  12. if(k==0&&n==0)
  13. {
  14. ret.push_back(path);
  15. return;
  16. }
  17. if(n<0||k<0) return;
  18. for(int i=pos;i<=9;++i)
  19. {
  20. path.push_back(i);
  21. dfs(k-1,n-i,i+1);
  22. path.pop_back();
  23. }
  24. }
  25. };

八、组合总和IV

. - 力扣(LeetCode)

该题和前面是类似的,但是用回溯算法,会超时

  1. class Solution {
  2. public:
  3. int combinationSum4(vector<int>& nums, int target) {
  4. vector<int> dp(target + 1);
  5. dp[0] = 1;
  6. for (int i = 1; i <= target; i++) {
  7. for (int& num : nums) {
  8. if (num <= i&& dp[i - num] < INT_MAX - dp[i])
  9. {
  10. dp[i] += dp[i - num];
  11. }
  12. }
  13. }
  14. return dp[target];
  15. }
  16. };

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/434262
推荐阅读
相关标签
  

闽ICP备14008679号