算法 - 组合

news/2024/4/29 10:54:34/文章来源:https://blog.csdn.net/qfc_128220/article/details/127440020

目录

题目来源

题目描述

示例

提示

题目解析

算法源码

剪枝优化 


题目来源

77. 组合 - 力扣(LeetCode)

题目描述

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

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

示例

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

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

提示

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

题目解析

这题就是求组合的问题。

组合和排列的区别在于,组合是无顺序性的,而排列是有顺序性的。

比如在[1,2,3]中任选两个数字的全排列有:

  • 12
  • 21
  • 13
  • 31
  • 23
  • 32

而全组合有:

  • 12
  • 13
  • 23

也就是说,对于组合来说12和21是同一个。

组合的求解也可以模拟为一个树结构

黄色部分是第一层选择完后,剩余可选数。

有人可能有疑问,为什么第一层选完2后,剩余可选数不是13,而是只有3呢?

我们假设第一层选完2后,剩余可选数是13,则

 最终会产生12和21这种重复组合。

因此组合的树结构,单层节点选择时,如果采用for顺序遍历的话,则后面层级节点选择起始位置 要比 前面层级节点选择起始位置 + 1。

比如第一层选择了1,则第二层从2开始选

比如第一层选择了2,则第二层从3开始选

只有这样才能避免重复。

组合由于和排列问题一样也能用树结构模拟,因此也可以用回溯算法,基于递归模型进行实现。

假设,从n个数中选择k个数,每层得到节点保存进path中,则当path.length === k 时,说明已经选择了path中已经保存了k个数,符合结束要求,结束递归。

每层节点选择没有特殊条件的话,即只要保证后面层级节点选择的起始位置,是上一层选择的节点的位置i的后一个,即i+1,这样才能保证无重复的组合。

算法源码

/*** @param {number} n* @param {number} k* @return {number[][]}*/
var combine = function(n, k) {let result = []dfs(n, k, 1, [], result)return result
};function dfs(n, k, index, path, result) {if(path.length === k) {return result.push([...path])}for(let i=index; i<=n; i++) {path.push(i)dfs(n, k, i+1, path, result)path.pop()}
}

剪枝优化 

题目中提示

1 <= k <= n

也就是说存在k===n的情况,比如我从4个数里面取4个,此时很显然只有一种组合,就是1234。但是按照上面算法源码逻辑,我们会出现如下图所示的递归过程

 当第一层取2时,第二层可选数字就只有3了,因此这个分叉的结果为23,由于不满足k=4,因此最终会丢弃。

剪枝优化,指的是,我们可以提前判断某分支是否符合最终要求,若不符合要求,则再其走递归流程前就结束它。

 比如当第一层选取2后,理论上还需要选择k-1=2个元素,但是实际上,第一层选完2后,只能选3了,即只剩余1个元素可选,因此我们不需要走完递归流程,也知道此分支的结果是不符合要求的,因此可以提前结束。

/*** @param {number} n* @param {number} k* @return {number[][]}*/
var combine = function(n, k) {let result = []dfs(n, k, 1, [], result)return result
};function dfs(n, k, index, path, result) {if(path.length === k) {return result.push([...path])}for(let i=index; i<=n; i++) {if(n - i + 1 < k - path.length) break // 剪枝path.push(i)dfs(n, k, i+1, path, result)path.pop()}
}

但是上面代码中的剪枝策略,依旧存在无意义的for循环遍历,循环的结束条件都放到了循环体中,因此可以继续优化

/*** @param {number} n* @param {number} k* @return {number[][]}*/
var combine = function(n, k) {let result = []dfs(n, k, 1, [], result)return result
};function dfs(n, k, index, path, result) {if(path.length === k) {return result.push([...path])}for(let i=index; i<=n-(k-path.length)+1; i++) { // 将剪枝条件整合到循环条件中,减少循环次数path.push(i)dfs(n, k, i+1, path, result)path.pop()}
}

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

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

相关文章

JavaScript——关于JavaScript、在HTML中嵌入JS代码的三种方式、变量

前言 近日无意间透过装了热水之后&#xff0c;散发出水蒸气的透明水杯看东西时&#xff0c;发现看到的东西呈现模糊效果&#xff0c;这种效果和毛玻璃效果类似。毛玻璃效果在web、手机系统上也有很多应用&#xff0c;如网页上的广告弹窗&#xff0c;手机系统的消息通知界面等等…

LeetCode刷题复盘笔记——131. 分割回文串(一文搞懂回溯解决经典的分割回文串问题)

今日主要总结一下&#xff0c;131. 分割回文串 题目&#xff1a;131. 分割回文串 Leetcode题目地址 题目描述&#xff1a; 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是 回文串 。返回 s 所有可能的分割方案。 回文串 是正着读和反着读…

目标检测——day46 可转移交互性知识的人机交互检测

Transferable Interactiveness Knowledge for Human-Object Interaction Detection论文pdf下载&#xff08;含笔记&#xff09;Transferable Interactiveness Knowledge for Human-Object Interaction Detection1 INTRODUCTION3 PRELIMINARY4 METHOD4.1 Overview4.2 Representa…

JVM——类加载子系统

文章目录一、类加载器子系统作用二、类加载过程1、加载&#xff08;Loading&#xff09;2、验证&#xff08;Verification&#xff09;3、准备&#xff08;Preparation&#xff09;4、解析&#xff08;Resolution&#xff09;5、初始化&#xff08;Initialization&#xff09;三…

SpringCloud微服务实践之三 创建子项目UserService

创建子项目UserService&#xff0c;并将服务注册到Eureka UserService子项目作为用户信息的服务提供方&#xff0c;通过本项目&#xff0c;可以实现对基于Docker运行的mysql数据库表的读取。 1、在父项目上点击鼠标右键选择new→Module&#xff1a; 过程同上&#xff0c;略过…

基于jeecgboot的flowable驳回修改以及发起人设置

昨晚升级代码生成器&#xff0c;支持生成权限注解和菜单的SQL,修改驳回bug,以后保存流程强制要求第一个用户任务节点必须是发起人节点。 1、前端增加发起人设置 <el-radio label"INITIATOR">发起人</el-radio> 相应代码 if (this.containsKey(this.bpmn…

MybatisPlus【SpringBoot】 3 基本CRUD

MybatisPlus【SpringBoot】 【【尚硅谷】2022版MyBatisPlus教程&#xff08;一套玩转mybatis-plus&#xff09;】 3 基本CRUD 文章目录MybatisPlus【SpringBoot】3 基本CRUD3.1 BaseMapper3.2 插入3.3 删除3.3.1 通过id 删除记录3.3.2 通过id 批量删除记录3.3.3 通过map 条件…

【Svelte】-(7)绑定|Each 块绑定 / audio video 媒体标签绑定 / client offset 尺寸绑定 / this / 组件绑定

文章目录Each 块绑定媒体标签绑定尺寸绑定this组件绑定Each 块绑定 您也可以在 Each 的过程中使用。 不过需要注意的是&#xff0c;与这些 <input> 交互会改变数组。当要使用不可变数据&#xff0c;应该去避免使用这些绑定&#xff0c;并且改用事件来处理这些内容。 <…

nvm切换node版本

在实际的前端开发过程中&#xff0c;可能会经常遇见 node.js 的版本问题&#xff0c;不同的项目需要使用不同的 node.js 版本。比如Vue2和Vue3需要的Node版本不一样。 地址&#xff1a;https://github.com/coreybutler/nvm-windows/releases 注意&#xff1a;安装之前必须完…

[LCT刷题][树链信息维护] P4332 [SHOI2014]三叉神经树

写在前面 把黑题看成蓝题结果想了老半天感觉不对劲 本题对于理解SplaySplaySplay和LCTLCTLCT结构具有至关重要的意义&#xff0c;值得反复思考。 可能因为我比较菜 题目思路 题目给定一个类似神经网络的东西&#xff0c;每个节点都具有激活层、三输入单输出&#xff0c;输…

node.js+vue+Web的疫情大数据平台分析系统

以往的疫情防控管理事务处理主要使用的是传统的人工管理方式&#xff0c;这种管理方式存在着管理效率低、操作流程繁琐、保密性差等缺点&#xff0c;长期的人工管理模式会产生大量的文本文件与文本数据&#xff0c;这对事务的查询、更新以及维护带来不少困难。随着互联网时代的…

Google共码未来 与 C站 创造者的经历

本人仅参加一天活动 2022.9.14&#xff1b;吃喝拉撒全免费哈哈哈 大会主题&#xff1a;共码未来 looker、chromium、wouldnt、jetpack looker https://blog.csdn.net/WebEye_Marketing/article/details/116047404 chromium https://blog.csdn.net/arv002/article/details/1…

SEO和SEM的区别是什么,哪个效果更好一些

SEO指的是搜索引擎优化&#xff0c;SEM指的是搜索引擎影响&#xff0c;那么SEO和SEM的区别具体是什么&#xff1f;对于初创业的企业来说&#xff0c;哪个更好呢&#xff1f;下面&#xff0c;本文将介绍SEO和SEM的区别&#xff0c;帮助企业和公司网络人员理清这两者的优劣势。 S…

【力扣刷题】Day31——DP专题

文章目录七、子序列问题&#xff08;线性DP and 区间DP&#xff09;1、子序列&#xff08;不连续&#xff09;29.最长递增子序列&#xff08;LIS&#xff09;30. 最长公共子序列 &#xff08;LCS&#xff09;31.不相交的线2、子序列&#xff08;连续&#xff09;32. 最长连续递…

C语言中的指针

一。什么是指针&#xff1f; 在计算机科学中&#xff0c;指针&#xff08;Pointer&#xff09;是编程语言中的一个对象&#xff0c;利用地址&#xff0c;它的值直接指向&#xff08;points to&#xff09;存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元&a…

一棋盘的麦子

14天阅读挑战赛 有一个古老的传说&#xff0c;一位国王的女儿不幸落水&#xff0c;水中有很多鳄鱼&#xff0c;国王情急之下下令&#xff1a; 来&#xff0c;就把女儿嫁给他。”很多人纷纷退让&#xff0c;一个勇敢的小伙子挺身而出&#xff0c;冒着生命危险把公 一看是个穷小子…

Java程序员快速掌握前端知识

Java程序员是一个需要终身学习的岗位&#xff0c;加之技术更新迭代越来越快&#xff0c;程序员们不得不坚持提升自己&#xff0c;上班可能接触到新事物&#xff0c;下班也要抓紧时间钻研&#xff0c;才能不被时代淘汰。 前端技术&#xff0c;Java程序员可以不精通&#xff0c;…

新手如何自学python?

对于初学者来说&#xff0c;视频教程相比于书籍更加直观有效&#xff0c;可以先看视频进行学习&#xff0c;然后再看书进行深刻学习~下面就给你分享下教程以及书籍~ 网站 1. 网易公开课 https://open.163.com/ 2. 腾讯课堂 https://ke.qq.com/ 3. 中国大学慕课 https://www.…

xxl-job反序列化漏洞分析复现

01 影响范围 Xxl-Job<2.1.2&#xff0c;需要利用Hessian触发。 02 环境搭建 下载地址&#xff1a;https://github.com/xuxueli/xxl-job/releases 修改配置文件 xxl-job-2.0.1/xxl-job-admin/src/main/resources/application.properties 修改数据库信息&#xff0c;以及…

动手写数据库:实现记录管理

在数据库中&#xff0c;数据以”记录“作为一个单元来存储&#xff0c;例如一个表的“一行”就对应一条记录。假设我们有一个表叫STUDENT&#xff0c;其中有name, age, sex, class等字段&#xff0c;那么一条记录的信息就由这四个字段对应的信息合成。一条记录如何存储并不是一…