LC77.组合

原题链接
原题链接

思路1:回溯

  • “叶子节点是数组的最后一个元素”类型的回溯模板题
  • 两种回溯办法:第一种,选择当前位置或者不不选择当前位置;第二种,遍历数组进行回溯

    代码1:

  • 数组的最后一个元素当作叶子节点

    1. class Solution {
    2. public:
    3. void backTrace(vector<vector<int>>& all_comb, vector<int>& cur_comb, int cur_sub, int n, int k) {
    4. if (cur_comb.size() == k) {
    5. all_comb.push_back(cur_comb);
    6. return;
    7. }
    8. if (cur_sub == n + 1) {
    9. return;
    10. }
    11. for (int i = cur_sub; i <= n; i++) {
    12. cur_comb.push_back(i);
    13. backTrace(all_comb, cur_comb, i + 1, n, k);
    14. cur_comb.pop_back();
    15. }
    16. }
    17. vector<vector<int>> combine(int n, int k) {
    18. vector<vector<int>> all_comb;
    19. vector<int> cur_comb;
    20. backTrace(all_comb, cur_comb, 1, n, k);
    21. return all_comb;
    22. }
    23. };
  • 选择当前位置或者不选

  1. class Solution {
  2. public:
  3. void dfs(int index, int k, int n, vector<vector<int>>& res, vector<int>& nums) {
  4. if (nums.size() == k) {
  5. res.push_back(nums);
  6. return ;
  7. }
  8. if (nums.size() + (n - index) < k) {
  9. return;
  10. }
  11. // 选择当前位置
  12. nums.push_back(index + 1);
  13. dfs(index + 1, k, n, res, nums);
  14. nums.pop_back();
  15. // 不选当前位置
  16. dfs(index + 1, k ,n, res, nums);
  17. }
  18. vector<vector<int>> combine(int n, int k) {
  19. vector<vector<int>> res;
  20. vector<int> nums;
  21. dfs(0, k, n, res, nums);
  22. return res;
  23. }
  24. };

思路2:二进制暴力枚举

  • situation进行枚举
  1. // n == 2
  2. // S 最大取到 (2 ^ n) - 1
  3. // 00 01 10 11 (100取不到)
  4. for (int S = 0; S < (1 << n); S++)
  • 从右往左读取位置(低位为1)
  1. // 如果第i低位是1,表示选取这个位置
  2. if (S & (1 << i))

代码2:

  1. class Solution {
  2. public:
  3. int getBinNum(int num) {
  4. int cnt = 0;
  5. for (int i = 0; i < 20; i++) {
  6. if (num & 1) {
  7. cnt += 1;
  8. }
  9. num >>= 1;
  10. }
  11. return cnt;
  12. }
  13. vector<vector<int>> combine(int n, int k) {
  14. // n == 2
  15. // S 最大取到 (2 ^ n) - 1
  16. // 00 01 10 11 (100取不到)
  17. vector<vector<int>> ans;
  18. for (int S = 0; S < (1 << n); S++) {
  19. if (getBinNum(S) == k) {
  20. vector<int> cur_s;
  21. for (int i = 0; i < n; i++) {
  22. if (S & (1 << i)) {
  23. cur_s.push_back(i + 1);
  24. }
  25. }
  26. ans.push_back(cur_s);
  27. }
  28. }
  29. return ans;
  30. }
  31. };