当前位置: 首页 > news >正文

回溯算法01-组合(Java)

1.组合

  • 题目描述

给定两个整数 nk,返回范围 [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这n个不同的数的组合问题,我们知道对于n个不同的数中的任意k个数组合,当n很大时通过枚举是很难将它枚举完成的,所以我们可以采用回溯算法来解决这一类问题。
  • 回溯算法的模板

1.确立递归函数及返回值

2.确立回溯的终止条件

3.单层递归逻辑

private void backtracking(参数) {//回溯的终止条件if (终止条件) {存放结果;return;}//回溯算法的遍历过程(集合的大小为树的宽度,递归的深度为树的深度)for (选择 :本层集合的元素) {处理节点;backtracking(路径, 选择列表);//递归回溯,撤销处理的结果}
}
1.首先我们确立递归函数及参数(例子:nums=[1,2,3] k = 2)
根据下图递归操作我们可以看出,每次挑选数组nums中的一个元素加入到集合之中:
第一次:集合元素为[1],剩余元素为[2,3]
第二次:集合元素为[1,2],剩余元素为[3] 此时集合[1,2]满足k = 2的组合条件,将其存储,因为之后不再再取3会使不满足k个数组合的条件,因此要进行回溯,返回到集合元素为[1],剩余元素为[2,3]
第三次:集合元素为[1,3],剩余元素为[] 此时要选择元素3加入到集合,因此我们要设置一个索引来避开元素2,这样才不会有重复
...依次回溯,我们发现每次叶子节点为我们想要的结果所以初始化一个回溯函数
void backtrack(int nums[], int startIndex) {}
nums为要组合的元素集合,startIndex为避免每次重复的指针2.设置终止条件:当我们组合的集合中恰好有k个节点时,表示组合完成3.单层递归逻辑
从startIndex开始,遍历所有可能的元素,将其添加到路径中,并递归调用backtrace方法继续生成下一个元素。完成递归后,需要将最后一个元素从路径中移除,以便尝试其他可能的元素。

image-20240305194217384

  • 以nums=[1,2,3,4] k = 2直观感受一下i与startIndex的变化
i = 1 s = 1 [1]
i = 2 s = 2 [1,2]
//i = 2 s = 2 [1]
i = 3 s = 2 [1,3]
//i = 3 s = 2 [1] 
i = 4 s = 2 [1,4]
//i = 4 s = 2 [1]
i = 2 s = 1 [2]
i = 3 s = 3 [2,3]
//i = 3 s = 3 [2]
i = 4 s = 3 [2,4]
//i = 4 s = 3 [2]
i = 3 s = 1 [3]
...
  • Java代码实现
//list:用于存储一条路径上的元素//result:用于返回最后的元素LinkedList<Integer> path = new LinkedList<>();List<List<Integer>> result = new LinkedList<>();public List<List<Integer>> combine(int n, int k) {backtrace(n, k, 1);return result;}//1.确立递归函数的参数及返回值//n:树的宽度即求n个数的组合数//k:叶子节点即组合个数为k//startIndex:用于开始元素遍历的起点private void backtrace(int n, int k, int startIndex) {//2.确立终止条件if (path.size() == k) {//当最后组成的元素集合为k时返回结果result.add(new LinkedList<>(path));return;}//3.单层递归逻辑for (int i = startIndex; i <= n; i++) {path.add(i);backtrace(n, k, i + 1);path.removeLast();}}

相关文章:

  • 数据库分库分表中间件选择
  • 【扩散模型系列1】扩散模型背景|DDPMs|LDM
  • 【理解机器学习算法】之Nearest Shrunken Centroid(纯Python)
  • Redis面试题
  • C++模拟揭秘刘谦魔术,领略数学的魅力
  • Python 程序基本结构的使用
  • 循环队列:一道使数据结构萌新知道什么是“愁滋味“的题目
  • 字符串逆序
  • web坦克大战小游戏
  • Verilog参数、Verilog参数和属性冲突、整数处理
  • 【ArcPy】简化ArcGISPro默认Python环境体量
  • YOLOv8从入门到入土使用教程!(二)目标预测
  • QT使用FFMPEG库开发视频播放器
  • 惠普 DsekJet GT 5810/5820常见问题及解决方法
  • 低代码平台开发——基于React(文末送书)
  • [笔记] php常见简单功能及函数
  • 【Linux系统编程】快速查找errno错误码信息
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • Android优雅地处理按钮重复点击
  • Brief introduction of how to 'Call, Apply and Bind'
  • JS笔记四:作用域、变量(函数)提升
  • js中的正则表达式入门
  • Markdown 语法简单说明
  • Otto开发初探——微服务依赖管理新利器
  • vue.js框架原理浅析
  • vue-router的history模式发布配置
  • 测试如何在敏捷团队中工作?
  • 翻译--Thinking in React
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 给自己的博客网站加上酷炫的初音未来音乐游戏?
  • 问:在指定的JSON数据中(最外层是数组)根据指定条件拿到匹配到的结果
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • .bat批处理(一):@echo off
  • .net 设置默认首页
  • .net 无限分类
  • .NET/C# 使用 SpanT 为字符串处理提升性能
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .NET企业级应用架构设计系列之技术选型
  • .secret勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复
  • @Builder用法
  • [C#]DataTable常用操作总结【转】
  • [c#基础]值类型和引用类型的Equals,==的区别
  • [Editor]Unity Editor类常用方法
  • [ERROR] 不再支持目标选项 5。请使用 7 或更高版本
  • [ESP32 IDF]web server
  • [Excel VBA]单元格区域引用方式的小结
  • [FC][常见Mapper IRQ研究]