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

【数据结构】回溯算法公式化解题 leetcode经典题目带刷:全排列、组合、子集

目录

    • 回溯算法
      • 一、什么是回溯算法
        • 1、基本思想:
        • 2、一般步骤:
      • 二、题目带练
        • 1、全排列
        • 2、组合
        • 3、子集
      • 三、公式总结

回溯算法

一、什么是回溯算法

回溯算法(Backtracking Algorithm)是一种解决组合问题排列问题选择问题等一类问题的常用算法。它通过尝试所有可能的选择来找到问题的解,当发现当前选择不符合要求时,就回溯到之前的状态,然后尝试其他的选择。

1、基本思想:

  1. 从问题的起始点开始,进行尝试,每次选择一个可能的路径。
  2. 如果发现当前选择无法达到解决问题的目标,就回退到上一个状态,尝试其他的选择。
  3. 不断地重复上述过程,直到找到解决问题的路径,或者遍历完所有可能的选择。

2、一般步骤:

  1. 确定问题的解空间和约束条件。
  2. 从解空间中选择一个可能的选择,进入下一步。
  3. 判断当前选择是否符合约束条件,如果符合,继续深入尝试下一步;如果不符合,回退到上一步。
  4. 重复上述步骤,直到找到解,或者遍历完所有可能的选择。

二、题目带练

1、全排列

题目地址
在这里插入图片描述
分析
看到这道题的描述,不难想到,如果我们要找出所有的排列方式,就要遍历n次数组,每次选择一个不重复元素排列在上次循环选择的元素后面,那这就出现了一个问题怎么对一个数组遍历n次?

显然这是不太可能实现的,因为n是不确定的,但是我们可以换一种思路,通过深度来代表遍历次数,也就是我们常说的回溯算法。

根据题意,我们应当设递归出口为 当前递归的深度 == 数组的长度if(depth == nums.length),同时保存当前的排列方式到集合中。ans.add(new ArrayList<>(path));每次递归的过程中我们需要遍历一次数组for(int i = 0; i < nums.length; i++),判断当前的元素是否被使用过if(used[i]),如果没被使用那么就将其记录下来,并且标记为使用过,继续进入递归path.add(nums[i]); used[i] = true;。当这次递归结束时dfs(nums,depth + 1,used);,撤销当前元素的使用标记,并且移除记录的集合。path.remove(path.size() - 1); used[i] = false;

效果就是调用方法后,先选择元素1path.add(nums[0]); used[0] = true;,再次调用方法记录深度+1dfs(nums,depth + 1,used);,此时发现1已经被选择过了,开始选择2path.add(nums[1]); used[1] = true;,调用递归,深度+1dfs(nums,depth + 1,used);,同理1,2被标记为使用过的元素,继续选择3path.add(nums[2]); used[2] = true;,然后递归结束。这里会退回到深度为2的那次选择,因为2之后还有别的元素可以选择,选择3后发现只有2可以选了,首选项为1的递归结束,依次类推得到所有排列方式。
在这里插入图片描述

代码如下:

class Solution {public List<List<Integer>> ans = new ArrayList<>();public List<Integer> path = new ArrayList<>();public List<List<Integer>> permute(int[] nums) {boolean[] used = new boolean[nums.length];dfs(nums,0,used);return ans;}public void dfs(int[] nums,int depth,boolean[] used){if(depth == nums.length){ans.add(new ArrayList<>(path));return;}for(int i = 0; i < nums.length; i++){if(used[i]){continue;}path.add(nums[i]);used[i] = true;dfs(nums,depth + 1,used);path.remove(path.size() - 1);used[i] = false;}}
}

2、组合

题目地址
在这里插入图片描述
分析

这道题与全排列的区别在于,全排列需要全部选择,而这道题不一定要全部选择,并且每个组合只能有一次,所以面对这道题,我们不能按照和之前同样的思路去解,因为无法排除同样组合的组合顺序问题。

那么我们要如何作出改动呢?

其实很简单,我们只需要让每次循环的起始值变为当前的深度即可,同时也不需要判断是否使用过了,因为我们只会向后找,不会从前开始往后找了。

class Solution {List<Integer> temp = new ArrayList<Integer>();List<List<Integer>> ans = new ArrayList<List<Integer>>();public List<List<Integer>> combine(int n, int k) {dfs(1, n, k);return ans;}public void dfs(int depth, int n, int k) {if (temp.size() == k) {ans.add(new ArrayList<Integer>(temp));return;}for(int i = depth;i <= n;i++){temp.add(i);dfs(i + 1, n, k);temp.remove(temp.size() - 1);}}
}

3、子集

题目地址
在这里插入图片描述
分析

大家看这道题可能会发现,是不是和组合有点相似?区别在哪呢,区别在于子集的选择长度不一定是n,而是[0,n]

其实我们只需要每次回溯都记录一次结果就好了。

class Solution {List<Integer> list = new ArrayList<>();List<List<Integer>> result = new ArrayList<>();public List<List<Integer>> subsets(int[] nums) {dfs(0,nums);return result;}public void dfs(int current, int[] nums){result.add(new ArrayList<>(list));if(current == nums.length){return;}for(int i = current; i < nums.length; i++){list.add(nums[i]);dfs(i + 1, nums);list.remove(list.size() - 1);}}
}

三、公式总结

如果认真看完的朋友可以发现,对于这种基础的回溯题目,我们都可以通过循环+回溯来解决问题,只需要根据具体问题来更改我们的循环条件即可。

当然这么做不一定是最好的,还有许多可以优化的地方,只是说大部分情况可以通过这种循环的方式来解决问题。

相关文章:

【数据结构】回溯算法公式化解题 leetcode经典题目带刷:全排列、组合、子集

目录 回溯算法一、什么是回溯算法1、基本思想&#xff1a;2、一般步骤&#xff1a; 二、题目带练1、全排列2、组合3、子集 三、公式总结 回溯算法 一、什么是回溯算法 回溯算法&#xff08;Backtracking Algorithm&#xff09;是一种解决组合问题、排列问题、选择问题等一类问…...

WPF基础入门-Class3-WPF数据模板

WPF基础入门 Class3&#xff1a;WPF数据模板 1、先在cs文件中定义一些数据 public partial class Class_4 : Window{public Class_4(){InitializeComponent();List<Color> test new List<Color>();test.Add(new Color() { Code "Yellow", Name &qu…...

js将搜索的关键字加颜色

js将搜索的关键字加颜色 使用正则匹配关键字并加入span标签&#xff0c;页面渲染时使用v-html渲染即可 // 文本框内容 let searchCont 测试;const reg new RegExp((${searchCont.value}), g); let data 图片保存测试A; data data.replace(reg, <span style"color:…...

Docker安装Oracle数据库打开、链接速度很慢

问题&#xff1a; 使用Docker安装Oracle数据库打开、链接速度很慢&#xff0c;明显的在在转圈严重影响效率。 解决&#xff1a; 排查到DNS时&#xff0c;发现宿主机DNS配置清空后&#xff0c;通过JDBC连接目标Oracle数据库速度很快 进入容器中进行测试&#xff0c;发现清空DNS…...

学生分班查询系统的创建与使用指南

开学季&#xff0c;负责分班工作的老师们又面临一个难题&#xff1a;如何公布分班结果&#xff1f;将结果放在学校官网上可能会让很多无关人员看到&#xff0c;而不放则会导致家长们纷纷打电话来询问。那么&#xff0c;有没有一种方法可以让家长们自行查看分班结果呢&#xff1…...

全套解决方案:基于pytorch、transformers的中文NLP训练框架,支持大模型训练和文本生成,快速上手,海量训练数据!

全套解决方案&#xff1a;基于pytorch、transformers的中文NLP训练框架&#xff0c;支持大模型训练和文本生成&#xff0c;快速上手&#xff0c;海量训练数据&#xff01; 1.简介 目标&#xff1a;基于pytorch、transformers做中文领域的nlp开箱即用的训练框架&#xff0c;提…...

ffmpeg

文章目录 libavcodec实现 libavformat实现libavfilter实现 libswscale实现对比libavfilter图像处理libswscale vs libyuvlibavutil 命令行工具ffmpeg例子 ffprobe例子 FFmpeg 是一个由 C 语言编写的开源跨平台音视频处理工具集&#xff0c;它具有模块化的架构。下面是 FFmpeg 的…...

CH03_代码的坏味道(下)

循环语句&#xff08;Loops&#xff09; 从最早的编程语言开始&#xff0c;循环就一直是程序设计的核心要素。如今&#xff0c;函数作为一等公民已经得到了广泛的支持&#xff0c;因此我们可以使用以管道取代循环&#xff08;231&#xff09;管道操作&#xff08;如filter和ma…...

journal日志导致服务器磁盘满

背景 ubuntu 18.04服务器磁盘突然100% 一查/var/log/journal目录占了14G 清理 要清理 journal 日志&#xff0c;可以使用以下步骤&#xff1a; 运行以下命令来查看 journal 日志的使用情况&#xff1a; journalctl --disk-usage这将显示 journal 日志的当前使用情况&#x…...

“Go程序员面试笔试宝典”复习便签

一.逃逸分析 1.1逃逸分析是什么&#xff1f; 逃逸分析&#xff0c;主要是Go编译器用来决定变量分配在堆或者栈的手段。 区分于C/C手动管理内存分配&#xff0c;Go将这些工作交给了编译器。 1.2逃逸分析有什么作用 解放程序员。程序员不需要手动指定指针分配内存。 灵活的…...

数组的度(指数组里任一元素出现频数的最大值)

题目&#xff1a; 给定一个非空且只包含非负数的整数数组 nums&#xff0c;数组的 度 的定义是指数组里任一元素出现频数的最大值。 你的任务是在 nums 中找到与 nums 拥有相同大小的度的最短连续子数组&#xff0c;返回其长度。 示例 1&#xff1a; 输入&#xff1a;nums …...

scala array类型参数

在Scala中&#xff0c;数组&#xff08;Array&#xff09;是一种用于存储相同类型元素的数据结构。数组可以用于保存基本数据类型和自定义数据类型的元素。当定义数组类型参数时&#xff0c;您通常是在函数、类或方法签名中使用它们。以下是一些有关Scala数组类型参数的示例&am…...

构建 NodeJS 影院预订微服务并使用 docker 部署(03/4)

一、说明 构建一个微服务的电影网站&#xff0c;需要Docker、NodeJS、MongoDB&#xff0c;这样的案例您见过吗&#xff1f;如果对此有兴趣&#xff0c;您就继续往下看吧。 你好社区&#xff0c;这是&#x1f3f0;“构建 NodeJS 影院微服务”系列的第三篇文章。本系列文章演示了…...

html写一个向flask_socketio发送消息和接收消息并显示在页面上

以下是一个简单的HTML页面&#xff0c;它包含一个输入框、一个发送按钮和一个显示区域。用户可以在输入框中输入消息&#xff0c;点击发送按钮&#xff0c;然后这个消息会被发送到 Flask-SocketIO 服务器。当服务器回应消息时&#xff0c;它会在页面的显示区域显示出来。 <…...

C#使用.Net Core进行跨平台开发

使用 .NET Core 进行跨平台开发是一种灵活的方法&#xff0c;可以在多个操作系统上运行 C# 应用程序。以下是在 C# 中使用 .NET Core 进行跨平台开发的一般步骤&#xff1a; 安装 .NET Core SDK&#xff1a; 在开始之前&#xff0c;需要安装适用于操作系统的 .NET Core SDK。可…...

Java“牵手”天猫店铺所有商品API接口数据,通过店铺ID获取整店商品详情数据,天猫API申请指南

天猫商城是一个网上购物平台&#xff0c;售卖各类商品&#xff0c;包括服装、鞋类、家居用品、美妆产品、电子产品等。天猫商品详情可以帮助消费者更好的了解宝贝信息&#xff0c;从而做出购买决策。同时&#xff0c;消费者也可以通过商品详情了解其他买家对宝贝的评价&#xf…...

php输入post过滤函数,入库出库,显示

第一部分 php输入post过滤函数 function GLOBAL_POST($str) {$str_origin$str; if (empty($str)) return false;$str str_replace( /, "", $str);//替换关键词 $str str_replace("\\", "", $str); $str str_replace("&gt", &…...

matlab-对数据集加噪声并实现tsne可视化

matlab-对数据集加噪声并实现tsne可视化 最近才知道&#xff0c;原来可以不用模型&#xff0c;也能实现对数据集数据的可视化。 **一、**以COIL-100数据集为例子。 问题&#xff1a; 前提&#xff1a;首先对COIL-100数据集根据角度0-175和180-255&#xff0c;分别划分成C1,C…...

【BASH】回顾与知识点梳理(三十八)

【BASH】回顾与知识点梳理 三十八 三十八. 源码概念及简单编译38.1 开放源码的软件安装与升级简介什么是开放源码、编译程序与可执行文件什么是函式库什么是 make 与 configure什么是 Tarball 的软件如何安装与升级软件 38.2 使用传统程序语言进行编译的简单范例单一程序&#…...

Sql注入攻击的三种方式

SQL注入是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。SQL 注…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...

Web后端基础(基础知识)

BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程序的逻辑和数据都存储在服务端。 优点&#xff1a;维护方便缺点&#xff1a;体验一般 CS架构&#xff1a;Client/Server&#xff0c;客户端/服务器架构模式。需要单独…...