蓝桥杯试题:DFS回溯

一、题目要求

输入一个数组n,输出1到n的全排列

二、代码展示

import java.util.*;public class ikun {static List<List<Integer>> list = new ArrayList<>();public static void main(String[] args) {    Scanner sc = new Scanner(System.in);int n = sc.nextInt();int[] v = new int[n + 1];List<Integer> res = new ArrayList<>();dfs(n,v,res);for (List<Integer> x:list){for (int y:x){System.out.print(y + " ");}System.out.println();}}public static void dfs(int n, int[] v, List<Integer> res) {// 终止条件:当当前排列长度等于n时if (res.size() == n) {// 深拷贝当前排列结果到结果集list.add(new ArrayList<>(res));return; // 结束当前递归分支}// 遍历所有数字1~nfor (int i = 1; i <= n; i++) {// 跳过已使用的数字(剪枝操作)if (v[i] == 1) continue;// 选择阶段:将数字i加入当前排列res.add(i);           // 操作路径v[i] = 1;             // 更新状态标记// 递归深入:探索下一层决策树dfs(n, v, res);       // 进入新的递归层级// 回溯阶段:撤销当前选择res.remove(res.size() - 1); // 移除最后一个元素(i)v[i] = 0;                   // 重置状态标记}}} 

核心逻辑

  1. 主方法(main)

    • 创建标记数组v(索引1到n标记数字是否被使用)。

    • 调用DFS函数生成排列。

    • 遍历结果列表list,输出所有排列。

  2. DFS方法(dfs)

    • 终止条件:当临时结果res的大小等于n时,将当前排列存入list

    • 递归过程

      • 遍历数字1到n。

      • 若当前数字未被使用(v[i] == 0):

        • 将数字加入res,并标记为已使用。

        • 递归调用DFS,继续生成剩余位置的排列。

        • 回溯:递归返回后,移除res末尾元素,并重置标记,以便尝试其他数字。

关键点分析

  • 标记数组v:用于避免重复使用数字。v[i] = 1表示数字i已被使用。

  • 回溯机制:在递归返回后,撤销当前选择(移除res末尾元素,重置标记),确保后续分支的正确性。

  • 结果存储:每次找到完整排列时,复制reslist(避免后续修改影响已存结果)。

三、DFS算法

1、DFS算法核心思想

深度优先搜索(DFS) 是一种"先探到底再回溯"的算法,其核心特征是:

  1. 优先沿着一条路径深入探索到底

  2. 遇到终点或无法继续时回溯到最近的分支点

  3. 通过递归或栈结构实现路径记录和状态回退

基础语法:

public static void dfs(){if (当前状态 == 目标状态){//逻辑处理return;}for (寻找新状态){if (状态合法){dfs(新状态);}}}

回溯

 public static void dfs(){if (当前状态 == 目标状态){//逻辑处理return;}for (查找新状态){if (状态合法){//标记当前状态已访问dfs(新状态);//撤销标记}}}

2、代码中的DFS实现解析

代码结构概览
static List<List<Integer>> list = new ArrayList<>(); // 存储所有排列结果public static void dfs(int n, int[] v, List<Integer> res) {// 终止条件if (res.size() == n) {list.add(new ArrayList<>(res)); // 保存当前排列return;}// 遍历所有可能选择for (int i = 1; i <= n; i++) {if (v[i] == 1) continue;  // 跳过已使用的数字// 做选择res.add(i);v[i] = 1;// 递归深入dfs(n, v, res);// 撤销选择(回溯)res.remove(res.size() - 1);v[i] = 0;}
}

3、代码与DFS原理的对应关系

DFS阶段代码实现说明
1. 路径选择res.add(i)将当前数字加入排列路径
2. 状态标记v[i] = 1标记该数字已被使用
3. 递归深入dfs(n, v, res)进入下一层决策树
4. 回溯恢复res.remove(...); v[i] = 0返回上层时撤销选择
5. 终止条件if (res.size() == n)当路径长度等于n时记录结果

4、执行流程演示(n=2)

初始调用:dfs(2, [0,0,0], [])↓
i=1被选中:res=[1], v=[0,1,0]→ 递归调用 dfs(2, [0,1,0], [1])↓i=2被选中:res=[1,2], v=[0,1,1]→ 记录结果 [1,2]← 回溯:res变为[1], v[2]=0← 返回上层← 回溯:res变为[], v[1]=0i=2被选中:res=[2], v=[0,0,1]→ 递归调用 dfs(2, [0,0,1], [2])↓i=1被选中:res=[2,1], v=[0,1,1]→ 记录结果 [2,1]← 回溯:res变为[2], v[1]=0← 返回上层← 回溯:res变为[], v[2]=0

5、算法特性分析

特性本代码中的体现
时间复杂度O(n!) - 需要生成n!种排列
空间复杂度O(n) - 递归栈深度为n
回溯机制通过removev[i]=0显式实现状态回退
剪枝优化使用v数组避免重复选择
结果存储使用new ArrayList<>(res)深度拷贝当前状态

6、DFS的典型应用场景

  1. 全排列/组合问题(如本代码所示)

  2. 迷宫路径搜索

  3. 树/图的遍历

  4. 棋盘类游戏解法(八皇后、数独等)

  5. 连通分量检测


通过这种递归+回溯的实现方式,DFS算法能系统性地遍历所有可能的解空间,特别适合需要穷举所有可能性的场景。代码中通过标记数组和列表操作,清晰地展现了DFS的核心思想。

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

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

相关文章

Ruby基础

一、字符串 定义 283.to_s //转为string "something#{a}" //定义字符串&#xff0c;并且插入a变量的值 something//单引号定义变量 %q(aaaaaaaaa) // 定义字符串&#xff0c;&#xff08;&#xff09;内可以是任何数&#xff0c;自动转义双引号%Q("aaaaa"…

基于提示驱动的潜在领域泛化的医学图像分类方法(Python实现代码和数据分析)

摘要 医学图像分析中的深度学习模型易受数据集伪影偏差、相机差异、成像设备差异等导致的分布偏移影响&#xff0c;导致在真实临床环境中诊断不可靠。领域泛化&#xff08;Domain Generalization, DG&#xff09;方法旨在通过多领域训练提升模型在未知领域的性能&#xff0c;但…

C#—Settings配置详解

C#—Settings配置详解 在C#项目中&#xff0c;全局配置通常指的是应用程序的设置&#xff08;settings&#xff09;&#xff0c;这些设置可以跨多个类或组件使用&#xff0c;并且通常用于存储应用程序的配置信息&#xff0c;如数据库连接字符串、用户偏好设置等。 Settings配置…

国自然面上项目|基于多模态MR影像的胶质母细胞瘤高危区域定位及预后预测研究|基金申请·25-02-28

小罗碎碎念 今天和大家分享一个面上项目&#xff0c;执行年限为2019.01&#xff5e;2022.12&#xff0c;直接费用为57万元。 胶质母细胞瘤&#xff08;GBM&#xff09;预后差且差异大&#xff0c;异质性是重要因素&#xff0c;临床手段难评价。影像组学为异质性研究提供方法&am…

Nat Mach Intell | AI分子对接算法评测

《Nature Machine Intelligence》发表重磅评测&#xff0c;系统评估AI与物理方法在虚拟筛选&#xff08;VS&#xff09;中的表现&#xff0c;突破药物发现效率瓶颈。 核心评测体系&#xff1a;三大数据集 研究团队构建了三个新型测试集&#xff1a; TrueDecoy&#xff1a;含14…

安路FPGA开发入门:软件安装与点灯与仿真(TangDynasty ModelSim)

文章目录 前言软件安装开发软件仿真软件 点灯测试代码编写与编译引脚分配固件下载 仿真测试ModelSim添加仿真库TangDynasty仿真设置进行仿真 后记 前言 最近因为工作需要用安路的FPGA&#xff0c;这里对安路FPGA开发相关流程做个记录。作为测试只需要一个核心板&#xff08;我这…

千峰React:外部库引用

flushSync强制刷新 如果不强制刷新是这样&#xff1a;每次count在下一轮才更新 import { useState, useRef } from react import { flushSync } from react-domfunction App() {const [count, setCount] useState(0)const refuseRef(null)const handleClick () > { setCo…

防火墙旁挂组网双机热备负载均衡

一&#xff0c;二层交换网络&#xff1a; 使用MSTPVRRP组网形式 VLAN 2--->SW3为主,SW4 作为备份 VLAN 3--->SW4为主,SW3 作为备份 MSTP 设计 --->SW3 、 4 、 5 运行 实例 1 &#xff1a; VLAN 2 实例 2 &#xff1a; VLAN 3 SW3 是实例 1 的主根&#xff0c;实…

结合PyMuPDF+pdfplumber,删除PDF指定文本后面的内容

🚀 一、需求场景解析 在日常办公中,我们经常会遇到这样的痛点: 合同处理:收到上百份PDF合同,需要找到"签署页"之后的内容并删除报表加工:批量移除财务报表中的敏感数据区域文档归档:快速提取技术文档的关键章节传统的手动操作方式存在三大致命缺陷: ❗ 耗时…

二、QT和驱动模块实现智能家居----2、编译支持QT的系统

因为我们的Linux内核文件不支持QT系统&#xff08;当然如果你的支持&#xff0c;完全跳过这篇文章&#xff09;&#xff0c;所以我们要从网上下载很多软件包&#xff0c;这里直接用百问网的软件包&#xff0c;非常方便。 一&#xff1a;Ubuntu 配置 1 设置交叉编译工具链 以…

el-select的下拉选择框插入el-checkbox

el-check注意这里要使用model-value绑定数据 <el-selectv-model"selectDevice"multiplecollapse-tags:multiple-limit"5"style"width: 200px"popper-class"select-popover-class" ><el-optionv-for"item in deviceList…

UNION 和 UNION ALL 的区别:深入解析 SQL 中的合并操作

在 SQL 的世界里&#xff0c;当我们需要合并多个查询结果集时&#xff0c;UNION和UNION ALL是两个常用的操作符。虽然它们的功能看起来相似&#xff0c;但实际上有着重要的区别&#xff0c;这些区别在不同的应用场景中会对查询结果和性能产生显著影响。本文将详细探讨UNION和UN…

5.Linux配置虚拟机

步骤一 步骤二 步骤三 步骤四 finalshell

2024华为OD机试真题-热点网站统计(C++)-E卷-100分

2024华为OD机试最新E卷题库-(C卷+D卷+E卷)-(JAVA、Python、C++) 目录 题目描述 输入描述 输出描述 用例1 用例2 考点 题目解析 代码 c++ 题目描述 企业路由器的统计页面,有一个功能需要动态统计公司访问最多的网页 URL top N。 请设计一个算法,可以高效动态统计 …

SOUI基于Zint生成EAN码

EAN码广泛应用与欧洲的零售业。包括EAN-2、EAN-5、EAN-8和EAN-12码。分别编码 2、5、7 或 12 位数字。此外&#xff0c;可以使用 字符将 EAN-2 和 EAN-5 附加符号添加到 EAN-8 和 EAN-13 符号中&#xff0c;就像 UPC 符号一样。 EAN-8校验码计算&#xff1a; 从左往右奇数位的…

QT实现简约美观的动画Checkbox

*最终效果: * 一共三个文件: main.cpp , FancyCheckbox.h , FancyCheckbox.cpp main.cpp #include <QApplication> #include "FancyCheckbox.h" #include <QGridLayout> int main(int argc, char *argv[]) {QApplication a(argc, argv);QWidget* w new…

arm | lrzsz移植记录

1 我的使用场景 开发板无网络, 无奈只得用U盘拷贝文件 文件不大, 每次都插拔U盘, 很繁琐 原来的环境不支持rz等命令 就需要移植这个命令来使用 下载地址 https://ohse.de/uwe/releases/lrzsz-0.12.20.tar.gz 2 编译脚本 # 主要内容在这里 configure_for_arm(){mkdir -p $PA…

Hadoop之01:HDFS分布式文件系统

HDFS分布式文件系统 1.目标 理解分布式思想学会使用HDFS的常用命令掌握如何使用java api操作HDFS能独立描述HDFS三大组件namenode、secondarynamenode、datanode的作用理解并独立描述HDFS读写流程HDFS如何解决大量小文件存储问题 2. HDFS 2.1 HDFS是什么 HDFS是Hadoop中的一…

矩阵 trick 系列 题解

1.AT_dp_r Walk&#xff08;矩阵图论&#xff09; 题意 一个有向图有 n n n 个节点&#xff0c;编号 1 1 1 至 n n n。 给出一个二维数组 A 1... n , 1... n A_{1...n,1...n} A1...n,1...n​&#xff0c;若 A i , j 1 A_{i,j}1 Ai,j​1 说明节点 i i i 到节点 j j j …

使用AoT让.NetFramework4.7.2程序调用.Net8编写的库

1、创建.Net8的库&#xff0c;双击解决方案中的项目&#xff0c;修改如下&#xff0c;启用AoT&#xff1a; <Project Sdk"Microsoft.NET.Sdk"><PropertyGroup><OutputType>Library</OutputType><PublishAot>true</PublishAot>&…