77. 组合(力扣LeetCode)

文章目录

  • 77. 组合
    • 题目描述
    • 回溯算法
    • 组合问题的剪枝操作

77. 组合

题目描述

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

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

示例 1:

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

示例 2:

输入:n = 1, k = 1
输出:[[1]]

提示:

  • 1 <= n <= 20
  • 1 <= k <= n

回溯算法

  • 对回溯算法不太了解的同学可以看这篇文章:回溯算法理论基础

  • 该题目的详细解析可以看这篇文章:第77题. 组合

看完这两篇文章后,可能有同学看懂了[12],[13],[14]组合中2,3,4是如何删除(回溯),但没看懂1是如何删除(回溯)的可以看下图:
在这里插入图片描述
代码如下:

// 定义解决方案类
class Solution {
public:// 组合的主要公共接口,返回所有可能的k个数的组合vector<vector<int>> combine(int n, int k) {// 从数字1开始进行回溯搜索backtracking(n, k, 1);// 返回搜索结果return result;}private:// 用来存放最终的组合结果vector<vector<int>> result;// 用于在递归过程中存放当前的组合路径vector<int> path;// 回溯函数,递归生成所有可能的组合void backtracking(int n, int k, int startindex) {// 如果当前路径的长度等于k,说明找到了一个长度为k的组合if (path.size() == k) {// 将当前路径加入到结果集中result.push_back(path);// 返回上一层递归return;}// 从startindex开始,尝试所有可能的下一个元素for (int i = startindex; i <= n; i++) {// 将当前元素加入到当前路径path.push_back(i);// 递归调用backtracking,注意下一次递归开始的索引是i+1,这样就不会有重复的组合backtracking(n, k, i + 1);// 将当前元素从路径中移除,也称为回溯path.pop_back();}// 如果循环结束,返回上一层递归return;}
};

在这个代码中:

  • 类Solution包含一个公共成员函数combine,它初始化回溯过程并返回结果。
  • backtracking是一个递归函数,用于执行回溯搜索。它接受当前数字的范围n,组合的长度k,以及当前搜索的起始索引startindex。
  • 私有成员result用于存储最终的组合结果;path用于在递归过程中跟踪当前的组合路径。
  • 在backtracking函数中,通过循环遍历startindex到n的所有数字,并将每个数字添加到当前路径path中。每添加一个数字,就递归调用backtracking,直到达到组合的长度k。到达长度k时,将当前路径path添加到结果列表result中。
  • 在每次递归调用之后,path需要回溯,即移除最后一个元素,以便下一次递归调用可以尝试新的数字组合。

这种方法能够避免重复的组合,因为每次递归都从下一个数字开始,而不是从头开始。这样就保证了每个数字只使用一次,同时也保证了组合是按顺序生成的。

组合问题的剪枝操作

详细解析可以看这篇文章:77.组合优化
在这里插入图片描述
代码如下:

// 定义Solution类,这是一个解决方案类
class Solution {
public:// combine函数用于获取所有可能的组合vector<vector<int>> combine(int n, int k) {// 从数字1开始递归回溯搜索backtracking(n, k, 1);// 返回最终的结果列表return result;}private:// result用于存储所有的组合vector<vector<int>> result;// path用于在递归中构建每个组合vector<int> path;// backtracking是核心的递归回溯函数void backtracking(int n, int k, int startindex) {// 如果当前路径中的数字数量已经达到k个,则将当前路径保存到结果列表中if (path.size() == k) {result.push_back(path);return;}// 进行循环,尝试所有可能的数// 注意:这里使用了优化,减少了搜索的范围,避免了不必要的递归// n - (k - path.size()) + 1是剪枝后的上界for (int i = startindex; i <= n - (k - path.size()) + 1; i++) {// 将当前数字i加入到当前组合路径中path.push_back(i);// 递归调用backtracking,进行下一层搜索,下一次搜索从i+1开始backtracking(n, k, i + 1);// 回溯,移除当前路径中的最后一个数字,回到上一步,尝试其它可能的数字path.pop_back();}// 当循环结束,返回上一层递归return;}
};

在这段代码中:

  • backtracking是一个递归函数,用于深入每一层搜索可能的组合。
  • path是一个临时向量,用于存储当前递归路径上的组合。
  • result是一个二维向量,用于存储所有有效的k个数的组合。
  • backtracking函数中的if语句是递归的终止条件,即当path的大小等于k时,将当前组合添加到结果中。
  • 循环中的i <= n - (k - path.size()) + 1是一个关键的优化,它保证了仅当还有足够的元素可供选择以填满剩余的位置时,循环才会继续。这样可以减少不必要的递归调用,提高算法的效率。

例如,如果n=4, k=2,并且目前path已经包含了一个元素(假设是1),则只需要在剩下的3个元素中选择一个(2, 3, 或4),而不需要再考虑选择1。如果当前path已经有两个元素,则循环不再进行,因为不需要更多元素。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/496477.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

农业四情监测设备为什么符合高标准农田建设

TH-Q3随着科技的不断进步&#xff0c;智慧农业正逐渐成为现代农业发展的重要方向。其中&#xff0c;农业四情监测系统以其独特的功能和优势&#xff0c;在高标准农田建设中发挥着越来越重要的作用。 一、农业四情监测系统的概念及功能 农业四情监测系统&#xff0c;顾名思义&am…

【Linux】进程信号 --- 信号的产生 保存 捕捉递达

文章目录 信号的感知信号的结构描述 一、信号的产生1.通过键盘发送信号2.通过系统调用发送信号 二、信号的保存&#xff08;PCB内部的两张位图和一个函数指针数组&#xff09;理解三张数据结构表block pending haldler 三、通过代码编写 理解 信号的保存和递达1.信号集操作的库…

基于java SSM springboot+redis网上水果超市商城设计和实现以及文档

基于java SSM springbootredis网上水果超市商城设计和实现以及文档 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 …

分布式一致性算法-Raft

分布式一致性算法Raft 分布式一致性问题Raft算法细节节点状态节点状态演变选举leader过程日志复制过程 选举leader初始的选举领导者故障后的选举拆分投票 日志复制网络分区 再看分布式一致性问题写在最后 分布式一致性问题 假设有一个单节点的系统&#xff0c;这个系统是一个数…

【日常聊聊】程序员是如何看待“祖传代码”的?

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;日常聊聊 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 方向一&#xff1a;祖传代码的历史与文化价值 方向二&#xff1a;祖传代码的技术挑战与机遇 方向三&#xff1a;祖传代码与现…

【零基础入门TypeScript】对象

目录 句法 示例&#xff1a;对象文字表示法 TypeScript 类型模板 示例&#xff1a;Typescript 类型模板 示例&#xff1a;对象作为函数参数 示例&#xff1a;匿名对象 鸭子打字 例子 对象是包含一组键值对的实例。这些值可以是标量值或函数&#xff0c;甚至是其他对象的…

react 路由的基本原理及实现

1. react 路由原理 不同路径渲染不同的组件 有两种实现方式 ● HasRouter 利用hash实现路由切换 ● BrowserRouter 实现h5 API实现路由切换 1. 1 HasRouter 利用hash 实现路由切换 1.2 BrowserRouter 利用h5 Api实现路由的切换 1.2.1 history HTML5规范给我们提供了一个…

GB28181 —— Ubuntu20.04下使用ZLMediaKit+WVP搭建GB28181流媒体监控平台(连接带云台摄像机)

最终效果 简介 GB28181协议是视频监控领域的国家标准。该标准规定了公共安全视频监控联网系统的互联结构, 传输、交换、控制的基本要求和安全性要求, 以及控制、传输流程和协议接口等技术要求,是视频监控领域的国家标准。GB28181协议信令层面使用的是SIP(Session Initiatio…

FPFH特征匹配以及ransac粗配准

一、代码 Python import open3d as o3d import numpy as npdef extract_points(point_cloud, salient_radius5, non_max_radius5, gamma_210.95, gamma_320.95, min_neighbors6):keypoints o3d.geometry.keypoint.compute_iss_keypoints(point_cloud,salient_radiussalient_…

【MATLAB源码-第151期】基于matlab的开普勒化算法(KOA)无人机三维路径规划,输出做短路径图和适应度曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 开普勒优化算法&#xff08;Kepler Optimization Algorithm, KOA&#xff09;是一个虚构的、灵感来自天文学的优化算法&#xff0c;它借鉴了开普勒行星运动定律的概念来设计。在这个构想中&#xff0c;算法模仿行星围绕太阳的…

Windows下查看端口占用以及关闭该端口程序

打开命令窗口 windowsR 输入 cmd 查看所有运行端口 netstat -ano 该命令列出所有端口的使用情况。 在列表中我们观察被占用的端口&#xff0c;比如是 80&#xff0c;首先找到它。 查看被占用端口对应的 PID netstat -aon|findstr "80" 回车执行该命令&#xff…

StarRocks——Stream Load 事务接口实现原理

目录 前言 一、StarRocks 数据导入 二、StarRocks 事务写入原理 三、InLong 实时写入StarRocks原理 3.1 InLong概述 3.2 基本原理 3.3 详细流程 3.3.1 任务写入数据 3.3.2 任务保存检查点 3.3.3 任务如何确认保存点成功 3.3.4 任务如何初始化 3.4 Exactly Once 保证…