王清欢Randy 王清欢Randy
首页
  • 编程语言

    • C/C++ 学习笔记
    • Golang 学习笔记
  • 算法分析

    • LeetCode 刷题笔记
  • 操作系统

    • Linux 基础
    • Vim 实用技巧
    • Shell 脚本编程
    • GDB 学习笔记
  • 开发工具

    • Git 学习笔记
  • 分布式理论

    • 共识算法
    • 分布式事务
  • 数据库内核

    • PostgreSQL
    • Postgres-XL
  • hidb
  • pgproxy
  • 实用技巧
  • 学习方法
  • 资源分享
GitHub (opens new window)
首页
  • 编程语言

    • C/C++ 学习笔记
    • Golang 学习笔记
  • 算法分析

    • LeetCode 刷题笔记
  • 操作系统

    • Linux 基础
    • Vim 实用技巧
    • Shell 脚本编程
    • GDB 学习笔记
  • 开发工具

    • Git 学习笔记
  • 分布式理论

    • 共识算法
    • 分布式事务
  • 数据库内核

    • PostgreSQL
    • Postgres-XL
  • hidb
  • pgproxy
  • 实用技巧
  • 学习方法
  • 资源分享
GitHub (opens new window)
  • 基础算法

    • 双指针

      • 双指针基础
      • 碰撞指针
      • 快慢指针
      • 滑动窗口
    • 二分查找

      • 基础应用
      • 边界收缩
      • 局部有序
    • 排序算法

      • 01八大排序
      • 02快速排序
      • 03归并排序
      • 04桶排序
      • 05堆排序
    • 优先搜索

      • 01递归
      • 02网格结构深度优先搜索
      • 03树结构深度优先搜索
      • 04图结构深度优先搜索
      • 05网格结构广度优先搜索
      • 06树结构广度优先搜索
      • 07图结构广度优先搜索
    • 回溯算法

      • 01递归
      • 02 子集问题
      • 03 全排列问题
      • 04 组合问题
        • LeetCode刷题笔记 回溯算法
          • 77 组合
          • 39 组合总和
          • 40 组合总和 II
      • 05 回溯搜索问题
  • 基础数据结构

    • 线性表与哈希表

      • 01数组
      • 02栈和队列
      • 03单调栈
      • 04优先队列
      • 05双端队列
      • 06哈希表
      • 07多重集合
      • 08前缀和
      • 09数据结构设计
    • 字符串

      • 01字符串比较
      • 02回文字符串
      • 03字符串匹配
      • 04字符串算术表达式
    • 单链表

      • 01链表基础操作
      • 02链表遍历
    • 二叉树

      • 01二叉树的属性
      • 02二叉树的操作
      • 03层次遍历
      • 04前中后序遍历
      • 05二叉搜索树的属性
      • 06二叉搜索树的操作
      • 07字典树
      • 08二叉搜索树BST
    • 图

      • 01二分图
      • 02拓扑排序
      • 03并查集
      • 04最小生成树
      • 05最短路径
  • 进阶算法

    • 贪心算法

      • 01跳跃游戏
      • 02分配问题
      • 03区间问题
    • 分治策略

    • 动态规划

      • 01一维动态规划
      • 02二维动态规划
      • 03分割型动态规划
      • 04子序列问题
      • 05背包问题
      • 06字符串编辑问题
      • 07股票交易问题
  • 其他内容

    • 数学问题

      • 01公倍数与公因数
      • 02质数问题
      • 03进制转换问题
      • 04数字字符串求和问题
      • 05众数问题
      • 06中位数问题
      • 07数字处理问题
      • 08随机数问题
    • 位运算

      • 01位运算基础
      • 02妙用异或运算
      • 03二进制特性
  • LeetCode刷题笔记
  • 基础算法
  • 回溯算法
王清欢
2023-03-24
目录

04 组合问题

# LeetCode刷题笔记 回溯算法

# 77 组合 (opens new window)

给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。

你可以按 任何顺序 返回答案。

输入:n = 4, k = 2
输出:
[
 [2,4],
 [3,4],
 [2,3],
 [1,2],
 [1,3],
 [1,4],
]

解析:

class Solution {
public:
    void bt(int n, int k, int start, vector<int>& track, vector<vector<int>>& ans){
        if(track.size()==k){
            ans.push_back(track);
            return;
        }
        for(int i=start;i<=n;++i){
            track.push_back(i);
            bt(n,k,i+1,track,ans);
            track.pop_back();
        }
    }

    vector<vector<int>> combine(int n, int k) {
        vector<int> track;
        vector<vector<int>> ans;
        bt(n,k,1,track,ans);
        return ans;
    }
};

# 39 组合总和 (opens new window)

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

输入:candidates = [2,3,6,7], target = 7 输出:[[2,2,3],[7]] 解释:2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。7 也是一个候选, 7 = 7 。仅有这两种组合。

解析:

class Solution {
public:
    void bt(vector<int> candidates, int target, int start, vector<int>& track, vector<vector<int>>& ans){
        // 超出总和减枝
        if(target < 0){
            return;
        }
        if(target==0){
            ans.push_back(track);
            return;
        }
        for(int i=start;i<candidates.size();++i){
            track.push_back(candidates[i]);
            bt(candidates,target-candidates[i],i,track,ans); // start 仍从 i 开始重复使用元素
            track.pop_back();
        }
        return;
    }

    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<int> track;
        vector<vector<int>> ans;
        bt(candidates,target,0,track,ans);
        return ans;
    }
};

# 40 组合总和 II (opens new window)

给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用 一次 ,解集不能包含重复的组合

输入: candidates = [10,1,2,7,6,1,5], target = 8, 输出: [ [1,1,6], [1,2,5], [1,7], [2,6] ]

解析:

class Solution {
public:
    void bt(vector<int>& candidates, int target, int start, vector<int>& track, vector<vector<int>>& ans, vector<bool>& visited){
        if(target < 0){
            return;
        }
        if(target==0){
            ans.push_back(track);
            return;
        }
        for(int i=start;i<candidates.size();++i){
            if(i>start && candidates[i] == candidates[i-1] && !visited[i-1]){
                continue;
            }
            track.push_back(candidates[i]);
            visited[i] = true;
            bt(candidates,target-candidates[i],i+1,track,ans,visited); // 元素不可重复利用,使用下一个即i+1
            visited[i] = false;
            track.pop_back();
        }
        return;
    }

    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        vector<int> track;
        vector<vector<int>> ans;
        vector<bool> visited(candidates.size(),false);
        sort(candidates.begin(),candidates.end());
        bt(candidates,target,0,track,ans,visited);
        return ans;
    }
};
上次更新: 2023/11/19, 12:55:48
03 全排列问题
05 回溯搜索问题

← 03 全排列问题 05 回溯搜索问题→

Theme by Vdoing | Copyright © 2023-2024 Wang Qinghuan | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式