回溯之组合

        来自百度百科的解释:回溯,计算机算法,回溯法也称试探法,它的基本思想是:从问题的某一种状态(初始状态)出发,搜索从这种状态出发所能达到的所有“状态”,当一条路走到“尽头”的时候(不能再前进),再后退一步或若干步,从另一种可能“状态”出发,继续搜索,直到所有的“路径”(状态)都试探过。这种不断“前进”、不断“回溯”寻找解的方法,就称作“回溯法”。
        常见的回溯问题有组合、排列、子集、分割和棋盘问题等。下面给出回溯算法的模板。

private void backtracking(参数1,参数2,...){
	if(递归终止条件){
		收集结果;
		return;
	}
	for(遍历集合){
		处理;
		backtracking(参数1,参数2,...); // 递归;
		回溯;
	}
}

组合

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

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

class Solution {
    List<List<Integer>> ans = new ArrayList<>();
    List<Integer> path = new ArrayList<>();
    public List<List<Integer>> combine(int n, int k) {
        backtracking(n, k, 1);
        return ans;
    }
    void backtracking(int n, int k, int startIndex){
    	// 递归终止条件
        if(path.size() == k){
            ans.add(new ArrayList<>(path));
            return;
        }
        // for循环遍历集合,这里的集合为[1, 2, 3, ..., n]
        for(int i = startIndex;i <= n;i++){
        	// 处理
            path.add(i);
            // 递归
            backtracking(n, k, i + 1);
            // 回溯
            path.remove(path.size() - 1);
        }
    }
}

        根据上述示例,详细说明上述代码的执行过程。首先定义收集所有组合的ans集合,定义一个集合path用于收集某个组合,如果符合条件,将其放入ans集合中。combine调用backtracking方法,最后返回ans集合。接下来,详细说明backtracking的执行过程。
        path为空,不符合if条件,进入for循环,i = startIndex = 1。将1放入集合path中,path为[1]。递归进入下一个backtracking中。path长度为1,不满足if,此时startIndex为2,i从2开始,将2加入path中,此时path为[1, 2],递归进入下一个backtracking中,满足if条件要求的path长度为2,将[1,2]放入ans集合中,并返回。返回到上一个backtracking中,执行回溯,将path最后一个元素2移除,path为[1]。继续执行for循环,刚开始startIndex为2,i从2开始,现在i++后,i等于3,将3放入path集合中,path为[1, 3]。递归进入下一个backtracking中,此时path长度为2,满足if要求的条件,将[1, 3]放入ans集合中,返回到上一个backtracking,执行回溯条件,将元素3从path中移除,path为[1]。继续执行for循环,i为4,将元素4放入path集合中,path为[1, 4],递归进入下一个backtracking中,此时path长度为2,满足if条件,将[1, 4]放入ans中,并返回到上一个backtracking,将4从path中移除。此时for循环遍历完成,backtracking执行完成,返回最开始的trackbacking,将元素1从集合中移除。path为空。
        继续执行for循环,i++后,i为2,将元素2加入path中,此时path为[2]。进入下一个backtracking中,startIndex为3,将元素3加入path中,path为[2, 3],递归进入下一个backtracking中,满足if条件,将[2, 3]加入ans集合中,递归返回上一个backtracking,将元素3从path集合中移除,path为[2]。i++,i为4,将元素4放入path中,path为[2, 4]。递归进入下一个backtracking中,path满足if条件,将[2, 4]放入ans集合中,并返回上一个backtracking,将4从path中移除,此时for循环遍历完成,递归返回最初的backtracking,将元素2从path中移除。
        继续执行for循环,将元素3加入到path中,path为[3],递归进入下一个backtracking,startIndex为4,因此i等于4,将元素4加入到path中,此时path为[3, 4],递归进入下一个backtracking中,满足if条件,将[3, 4]加入ans集合,递归返回上一个backtracking,将元素4从path中移除,path为[3],此时for循环遍历结束,返回到最初的backtracking中,将元素3从path集合中移除,path为空。
        继续执行for循环,将元素4加入到path中,path为[4],递归进入下一个backtracking,此时startIndex为5,大于4,不进入for循环,递归返回最初的for循环,i++,大于4,最初backtracking方法的for循环执行结束,返回到combine方法中,并返回ans。
        在上述代码中,backtracking方法中传入startIndex参数,用于标记下一轮for循环应该从哪个元素开始遍历。还可以发现在最初for循环遍历到元素4时,起始没有必要继续递归下去,也就是说集合中剩余元素小于题目要求的组合数k减去path的长度时,可以直接返回,这就是剪枝操作,去掉不必要的遍历。

class Solution {
    List<List<Integer>> ans = new ArrayList<>();
    List<Integer> path = new ArrayList<>();
    public List<List<Integer>> combine(int n, int k) {
        backtracking(n, k, 1);
        return ans;
    }
    void backtracking(int n, int k, int startIndex){
        // 剪枝
        if(n - startIndex + 1 < k - path.size()){
            return;
        }
    	// 递归终止条件
        if(path.size() == k){
            ans.add(new ArrayList<>(path));
            return;
        }
        // for循环遍历集合,这里的集合为[1, 2, 3, ..., n]
        for(int i = startIndex;i <= n;i++){
        	// 处理
            path.add(i);
            // 递归
            backtracking(n, k, i + 1);
            // 回溯
            path.remove(path.size() - 1);
        }
    }
}

参考:带你学透回溯算法(理论篇)| 回溯法精讲!

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

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

相关文章

Python高级编程-DJango1

Python高级编程 灵感并不是在逻辑思考的延长线上产生 而是在破除逻辑或常识的地方才有灵感 目录 Python高级编程 1.python学习之前的准备 ​编辑 2.DJango 开发网站 3.创建项目 4.&#xff44;&#xff4a;&#xff41;&#xff4e;&#xff47;项目结构介绍 &#xff11;&…

转行HiL测试工程师

转行没方向&#xff1f;0基础也能转新能源汽车HiL测试岗位&#xff01; 都2024年了&#xff0c;不会还有同学想往软件测试、车载测试方向转吧&#xff01;996、卷经验、卷待遇… ❓❓❓❓想转行没有方向&#xff1f; 建议选择发展前景好的行业&#xff0c;转行前先找好行业&…

目标检测——打架视频数据集

引言 亲爱的读者们&#xff0c;您是否在寻找某个特定的数据集&#xff0c;用于研究或项目实践&#xff1f;欢迎您在评论区留言&#xff0c;或者通过公众号私信告诉我&#xff0c;您想要的数据集的类型主题。小编会竭尽全力为您寻找&#xff0c;并在找到后第一时间与您分享。 …

C++ | Leetcode C++题解之第73题矩阵置零

题目&#xff1a; 题解&#xff1a; class Solution { public:void setZeroes(vector<vector<int>>& matrix) {int m matrix.size();int n matrix[0].size();int flag_col0 false;for (int i 0; i < m; i) {if (!matrix[i][0]) {flag_col0 true;}for …

【Markdown笔记】——扩展语法学习part3 表格脚注标题编号(锚点)列表删除线人物列表(todo列表)emoji等

【Markdown笔记】——扩展语法学习part3 表格&脚注等 MarkdownMarkdown 表格语法表格内容居中、左对齐、右对齐 Markdown 脚注语法Markdown 标题编号语法Markdown 列表语法Markdown 删除线语法Markdown 任务列表语法Markdown 使用 Emoji 表情 前几篇markdown相关博客&#…

基于 Spring Boot 博客系统开发(七)

基于 Spring Boot 博客系统开发&#xff08;七&#xff09; 本系统是简易的个人博客系统开发&#xff0c;为了更加熟练地掌握 SprIng Boot 框架及相关技术的使用。&#x1f33f;&#x1f33f;&#x1f33f; 基于 Spring Boot 博客系统开发&#xff08;六&#xff09;&#x1f…

2024年第十三届工程与创新材料国际会议(ICEIM 2024)即将召开!

2024年第十三届工程与创新材料国际会议&#xff08;ICEIM 2024&#xff09;将于2024年9月6-8日在日本东京举行。ICEIM 2024由东京电机大学主办&#xff0c;会议旨在材料科学与工程、材料特性、测量方法和应用等相关领域进行学术交流与合作&#xff0c;在材料的微观世界里&#…

异或的使用在机器人项目上的应用||位运算符在智能驾驶项目上的应用

目录 一、异或的使用在机器人项目上的应用 二、异或&#xff08;XOR&#xff09;操作的几个特点 三、位运算符在智能驾驶项目上的应用 一、异或的使用在机器人项目上的应用 在当时负责皮带机器人项目中&#xff0c;就有一个很好的应用。此时需要设置电机驱动模块、编码器驱动…

Leetcode—724. 寻找数组的中心下标【简单】

2024每日刷题&#xff08;129&#xff09; Leetcode—724. 寻找数组的中心下标 实现代码 class Solution { public:int pivotIndex(vector<int>& nums) {int sum accumulate(nums.begin(), nums.end(), 0);int prefix 0;for(int i 0; i < nums.size(); i) {i…

为antd design vue组件库中的表格添加斑马线、鼠标悬浮表格中字体转变颜色的效果

前言&#xff1a; 在公司完成UI设计稿时&#xff0c;需要实现antd design vue组件库中的表格展示斑马线样式&#xff0c;同时具有鼠标悬浮表格中字体转变颜色的效果&#xff0c;经过多次尝试&#xff0c;最终实现&#xff0c;总结如下&#xff1a; <style lang"scss&q…

软件测试经理工作日常随记【2】-接口自动化

软件测试主管工作日常随记【2】-接口自动化 1.接口自动化 jmeter-反电诈项目 这个我做过的一个非常有意义的项目&#xff0c;和腾讯合作的&#xff0c;主要为用户拦截并提示所有可能涉及到的诈骗类型&#xff0c;并以裂变的形式扩展用户&#xff0c;这个项目前期后端先完成&…

ubuntu22.04:软件包 wps-office 需要重新安装,但是我无法找到相应的安装文件

错误原因&#xff1a;手动在wps官网上下载的linux deb版本的wps2019,想卸载但是一直报错 解决办法&#xff1a;执行如下命令 sudo rm -rf /var/lib/dpkg/info/wps-office*sudo dpkg --remove --force-remove-reinstreq wps-office 说明&#xff1a; sudo命令是以root执行&…

FIFO Generate IP核AXI接口配置全解

当需要在设计中使用自定义IP时&#xff0c;可以通过为IP核的各种参数指定值来进行定制。以下是一般步骤的概述&#xff1a; 首先是从IP catalog中选择IP核。 然后双击这个选定的IP核&#xff0c;打开一个定制向导或参数设置窗口。或在工具栏或右键菜单中选择“Customize IP”命…

SAPUI5基础知识1 - 概览,库,支持工具,自学教程

1. SAPUI5 概览 1.1 SAPUI5 SAPUI5是一种用于构建企业级Web应用程序的开发框架。它是由SAP开发的&#xff0c;基于HTML5、CSS3和JavaScript技术。 SAPUI5提供了一套丰富的UI控件和工具&#xff0c;使开发人员能够快速构建现代化、可扩展和可定制的应用程序。 它还提供了数据…

STM32CubeMX学习笔记32---FreeRTOS资源管理

一、CPU利用率简介 1 基本概念 CPU 使用率其实就是系统运行的程序占用的 CPU 资源&#xff0c;表示机器在某段时间程序运行的情况&#xff0c;如果这段时间中&#xff0c;程序一直在占用 CPU 的使用权&#xff0c;那么可以人为 CPU 的利用率是 100%。CPU 的利用率越高&#xf…

JVM调参实践总结

JVM调优–理论篇从理论层面介绍了如何对JVM调优。这里再写一篇WIKI&#xff0c;尝试记录下JVM参数使用的最佳实践&#xff0c;注意&#xff0c;这里重点介绍HotSpot VM的调参&#xff0c;其他JVM的调参可以类比&#xff0c;但不可照搬。 Java版本选择 基于Java开发应用时&…

面向新手在无人机竞速场景下的飞行辅助系统——浙大 FAST-Lab 高飞团队 ICRA 论文三项 Best Paper 入围

恭喜浙江大学 FAST-Lab 钟宇航同学的论文 A Trajectory-based Flight Assistive System for Novice Pilots in Drone Racing Scenario 顺利发表 ICRA 2024&#xff0c;并同时入选三项 Finalist&#xff1a; the IEEE ICRA Best Conference Paper Awardthe IEEE ICRA Best Pape…

干货!Kali Linux命令大全(建议收藏)

系统信息 arch 显示机器的处理器架构 name -m 显示机器的处理器架构 name -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 -(SMBIOS/DMI) hdparm -i /dev/hda 罗列一个磁盘的架构特性 hdparm -tT /dev/sda 在磁盘上执行测试读取操作 cat /proc/cpuinfo …

[综合应用]dns nfs httpd php mysql

第一步&#xff1a;搭建三台主机 主机名称 Ip地址 角色 503A 192.168.68.10 Mysql从 503B 192.168.68.11 Mysql从&#xff0c;nfs服务端&#xff0c;dns服务端 503Cmysql 192.168.68.12 MySQL主&#xff0c;web客户端 第二步&#xff1a;在503B上配置DNS 2.1 下载…

【3dmax笔记】027:配置修改器集、工具栏自定义与加载

文章目录 一、配置修改器集二、自定义工具栏三、加载工具栏 一、配置修改器集 可以把自己常用的修改命令放到右边框中的部分&#xff0c;便于自己的操作&#xff0c;省去了每次都要花半天时间找命令的尴尬。新建一个二维或者三维物体&#xff0c;点击修改面板&#xff0c;点击…
最新文章