DFS(一)深度优先搜索(Depth First Search)一条道走到黑

news2024/11/25 3:00:56

目录

一、盒子与扑克牌

二、员工的重要性

三、图像渲染


一、盒子与扑克牌

假如有编号为1~3的3张扑克牌和编号为1~3的3个盒子,现在需要将3张牌分别放到3个盒子中去,且每个盒子只能放
一张牌,一共有多少种不同的放法。
当走到一个盒子面前的时候,到底要放那一张牌呢?在这里应该把所有的牌都尝试一遍。假设这里约定一个顺
序,按牌面值从小到大依次尝试。在这样的假定下,当走到第一个盒子的时候,放入1号牌。
放好之后,继续向后走,走到第二个盒子面前,此时还剩2张牌,牌面值最小的为2号牌,按照约定的规则,把2
号牌放入第二个盒子。
此时,来到第三个盒子面前,只剩一张牌,放入第三个盒子。此时手中的牌已经用完。
继续向后走,走到了盒子的尽头,后面再也没有盒子,并且也没有可用的牌了,此时,一种放法已经完成了,
但是这只是一种放法,这条路已经走到了尽头,还需要折返,重新回到上一个盒子。
这里回到第三个盒子,把第三个盒子中的牌取出来,再去尝试能否再放其它的牌,这时候手里仍然只有一张3号
牌,没有别的选择了,所以还需要继续向后回退,回到2号盒子面前。
收回2号盒子中的2号牌,现在手里有两张牌,2,3,按照约定,再把3号牌放入2号盒子,放好之后,继续向后
走,来到3号盒子。
此事手里只有一张2号牌,把它放入3号盒子,继续向后走。
此时这条路又一次走到了尽头,一个新的放法又产生了,继续向上折返,尝试其它可能,按照上述步骤,依次
会产生所有结果。
代码如何实现这种过程呢?最主要的事情,向面前的盒子里放每一种牌,一个for循环搞定。这里还需考虑,现在手里有没有这张牌,用一个数组book标记手里是否有这张牌
 

void DFS(vector<int>& book, vector<int>& box, int idx, int n)
{
	// 遍历到最后一个元素返回
	if (idx == n+1)
	{
		for (int i = 1; i <= n; i++)
			cout << box[i] << " ";
		cout << endl;
		return;
	}
	for (int i = 1; i <= n; i++)
	{
		if (book[i] == 0)
		{
			box[idx] = i;//第idx盒子放第i张牌
			book[i] = 1;
			// 处理下一个
			DFS(book, box, idx + 1, n);
			// 回收
			book[i] = 0;
		}
	}
}

void test1()
{
	int n;
	cin >> n;
	vector<int> book(n + 1, 0);
	vector<int> box(n + 1, 0);
	DFS(book, box, 1, n);
}

二、员工的重要性

690. 员工的重要性icon-default.png?t=MBR7https://leetcode.cn/problems/employee-importance/

给定一个保存员工信息的数据结构,它包含了员工 唯一的 id ,重要度 和 直系下属的 id 。

比如,员工 1 是员工 2 的领导,员工 2 是员工 3 的领导。他们相应的重要度为 15 , 10 , 5 。那么员工 1 的数据结构是 [1, 15, [2]] ,员工 2的 数据结构是 [2, 10, [3]] ,员工 3 的数据结构是 [3, 5, []] 。注意虽然员工 3 也是员工 1 的一个下属,但是由于 并不是直系 下属,因此没有体现在员工 1 的数据结构中。

现在输入一个公司的所有员工信息,以及单个员工 id ,返回这个员工和他所有下属的重要度之和。

 首先将所有员工id与员工结点存入哈希表中

从给出的id作为根节点开始进行结点值importance的计算

遍历每一个员工id对应的下属id,继续dfs其下属id以下部分的importance

/*
// Definition for Employee.
class Employee {
public:
    int id;
    int importance;
    vector<int> subordinates;
};
*/

class Solution {
public:
    map<int, Employee*> mp;
    int dfs(int id)
    {
        int num = mp[id]->importance;
        for(auto e : mp[id]->subordinates)    // 遍历该id对应的下属id
        {
            num += dfs(e);
        }
        return num;
    }
    int getImportance(vector<Employee*> employees, int id) {
        // 用哈希表来保存每个id对应的员工
        for(auto e : employees)
            mp[e->id] = e;
        return dfs(id);
    }
};

三、图像渲染

733. 图像渲染icon-default.png?t=MBR7https://leetcode.cn/problems/flood-fill/

有一幅以 m x n 的二维整数数组表示的图画 image ,其中 image[i][j] 表示该图画的像素值大小。

你也被给予三个整数 sr ,  sc 和 newColor 。你应该从像素 image[sr][sc] 开始对图像进行 上色填充 。

为了完成 上色工作 ,从初始像素开始,记录初始坐标的 上下左右四个方向上 像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应 四个方向上 像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为 newColor 。

最后返回 经过上色渲染后的图像 。

 总的来说就是从给出起点开始,把与它相接的图块都染成和它一样的颜色。

总体DFS思路就是从起点开始染色,然后上下左右移动,移动完之后判断是否越界,如果不越界并且新位置没有被走过并且颜色需要被涂改就DFS该位置。(注意这个方向矩阵的引入,一般情况下我都会写出四次判断来进行哈哈哈哈)

从圈圈开始,涂改所有颜色为绿色的块

int nextP[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};

class Solution {
public:
    void DFS(vector<vector<int>>& image, int row, int col, vector<vector<bool>>& book, 
    int curX, int curY, int oldcolor, int newcolor)
    {
        // 先进行渲染当前颜色
        image[curX][curY] = newcolor;
        book[curX][curY] = true;

        // 判断上下左右位置是否需要渲染
        for(int i = 0; i < 4; i++)
        {
            int newX = curX + nextP[i][0];
            int newY = curY + nextP[i][1];

            // 判断下一个位置是否越界
            if(newX>=row||newX<0||newY>=col||newY<0)
                continue;
            if(book[newX][newY]==false && image[newX][newY]==oldcolor)
                DFS(image, row, col, book, newX, newY, oldcolor, newcolor);
        }
    }
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
        if(image.empty())
        return image;
        int row = image.size();
        int col = image[0].size();
        vector<vector<bool>> book(row, vector<bool> (col, false));
        int oldcolor = image[sr][sc];
        DFS(image, row, col, book, sr, sc, oldcolor, color);
        return image;
    }
};

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

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

相关文章

【Python-Django】医疗辅助平台-数据库设计-day2.1

操作需知&#xff1a; MySQL存储很长500的汉字选用字符类型_mysql字符串太长用什么存_信息时代弄潮儿的博客-CSDN博客 mysql中的Varchar(255)可以放多少个汉字_Ecloss的博客-CSDN博客_varchar255能存多少汉字 MySQL中的Text类型_SlowIsFastLemon的博客-CSDN博客_text类型 …

自制win10 PE usb启动盘教程

拿出祖传的U盘&#xff08;16GB&#xff09;安装老白菜根据教程制作U盘然后在U盘ios文件夹里面放入从系统之家下载的win10 ios文件包然后把U盘插入需要安装的电脑上面重启电脑按住F10打开BIOS设置界面USB启动设置为<启用>将UEFI和传统模式下的&#xff1a;U盘/USB硬盘USB…

【数据结构前言】

前言&#xff1a; 在之前我们已经有了C语言的基础&#xff0c;掌握了一些基本知识过后我们就可以进行其他方面的学习了&#xff0c;继我们学完C语言之后我们将会学习数据结构的相关知识&#xff0c;今天先让大家对其进行初步的认识&#xff01; 目录1. 什么是数据结构&#xff…

SpringCloud(13):分布式配置中心

1 为什么需要分布式配置中心&#xff1f; 在分布式系统中&#xff0c;由于服务数量巨多&#xff0c;为了方便服务配置文件统一管理&#xff0c;所以需要分布式配置中心组件。在Spring Cloud中&#xff0c;有分布式配置中心组件spring cloud confifig &#xff0c;它支持配置服…

增量式PID控制算法及仿真

当执行机构需要的是控制量的增量&#xff08;例如驱动步进电机&#xff09;时&#xff0c;应采用增量式PID控制。根据递推原理可得&#xff1a;增量式PID控制算法:根据增量式PID控制算法&#xff0c;设计了仿真程序&#xff0c;被控对象如下:PID控制参数:kp8&#xff0c;ki 0.1…

普中科技MicroPython基于esp32的基础教程-02

容器类型数据 序列 存放多值的连续内存空间&#xff0c;并且通过编号访问&#xff0c;其实就是类似于C语言的数组&#xff0c;相同数据类型、连续内存空间、使用下标访问 序列索引 支持正负操作&#xff0c;0到N&#xff0c;-N到-1 &#xff0c;但是C语言不支持负操作 个人觉…

温度、压力、物位仪表工作原理

温度、压力、物位仪表工作原理 一、温度仪表 1、温度仪表通常分一次仪表与二次仪表&#xff0c;一次仪表通常为&#xff1a;热电偶、热电阻、双金属温度计、就地温度显示仪等。二次仪表通常为温度记录仪、温度巡检仪、温度显示仪、温度调节仪、温度变送器等。 2、温度测量仪表…

Java基础进阶

Stream流 引例 需求&#xff1a;按照下面要求完成集合的创建和遍历 创建一个集合&#xff0c;存储多个字符串元素 1. 把所有以“曹”开头的元素存储到新集合中 2. 把曹开头&#xff0c;长度为3的元素存储到新集合中 List<String> list List.of("曹操", "…

【6s965-fall2022】剪枝✂pruningⅡ

剪枝比例 问题&#xff1a;我们应该如何找到每层的剪枝比率&#xff1f; 较浅的层&#xff0c;低层次的特征较深的层&#xff0c;抽象的特征 问题&#xff1a;哪些层的冗余度最高&#xff1f; 非统一剪枝&#xff08;每一层的稀疏度不一样&#xff09;比统一剪枝&#xff0…

python学习 --- 集合基础

目录 一、什么是集合&#xff1f; 二、集合的创建方式 1、直接使用{} 2、使用内置函数set() 三、集合的相关操作 1、集合元素的判断 2、集合元素的新增 3、集合元素的删除 四、集合间的关系 五、集合的数学操作 1、交集操作 2、并集操作 3、差集操作 4、对称差集…

基于微信小程序的校园商铺系统小程序

文末联系获取源码 开发语言&#xff1a;Java 框架&#xff1a;ssm JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 浏览器…

2022大数据产业年度“国产化优秀代表厂商”榜单发布,亚信科技AntDB数据库位列其中

国产化/信创亚信科技 ‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 亚信科技也做数据库&#xff1f;实际上亚信科技AntDB是我国最早的国产数据库产品之一&#xff0c;是在21世纪初国外品牌数据库无法满足我国暴涨的通信需求的情况下&#xff0c;为了帮助通信运用商更好…

普中科技手把手教你学ESP32--基于MicroPython-02

第四讲&#xff1a;LED灯实验 MicroPython函数使用 本来需要加入machine.的&#xff0c;但是我引入了form machine import Pin就可以直接省略了 machine是一个模块&#xff0c;Pin是machine中的一个功能 Micropython官网学习 点击DOCS文档 选择相应的芯片 查看对应的模块 …

LeetCode 1801. 积压订单中的订单总数(C++)

思路&#xff1a; 该题主要是对比销售、采购的价格来进行数组\队列的pop和push操作来实现&#xff1b;采用优先队列来实现排序&#xff0c;其中销售和采购对应小队列和大队列 对于 销售 操作&#xff1b;如果采购的积压订单中有出价格比自己的销售价格高&#xff0c;就出 对于 …

C++设计模式(7)——外观模式

外观模式 亦称&#xff1a; Facade 意图 外观模式是一种结构型设计模式&#xff0c; 能为程序库、 框架或其他复杂类提供一个简单的接口。 问题 假设你必须在代码中使用某个复杂的库或框架中的众多对象。 正常情况下&#xff0c; 你需要负责所有对象的初始化工作、 管理其…

29.Isaac教程--调整导航

调整导航 ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html 文章目录调整导航定位器全局规划器局部规划器控制器定位器 定位器是导航堆栈的关键部分&#xff0c;因为了解机器人的位置对于正确导航到目的地至关重要。 因此&#xff0c;快速准确的定…

2、threejs官网本地化部署启动和Parcel热加载:Web应用打包工具介绍及使用

一、Three.js 官网 背景&#xff1a; threejs 是国外的网站&#xff0c;访问有时候比较卡&#xff0c;所以建议本地化部署启动一下&#xff0c;方便随时访问学习。 部署方案&#xff1a; 1、访问Threejs官网 2、点击github 选择 dev版本下载 3、下载完之后&#xff0c;解压…

Java中的this关键字

介绍 this关键字用于引用当前实例&#xff0c;在Java语言中&#xff0c;当创建一个对象后&#xff0c;Java虚拟机就会为其分配一个指向对象本身的指针&#xff0c;这个指针就是“this”。 Java关键字this只能用于方法方法体内&#xff0c;在类中的非静态方法中使用&#xff0…

14 Java集合(集合框架+泛型+ArrayList类+LinkedList类+Vector类+HashSet类等)

本篇主要是集合框架基础和List集合&#xff0c;Map集合等等后续更 集合14.1 集合框架14.1.1 概念14.1.2 集合架构14.2 Collection接口14.2.1 常用方法14.3 迭代器14.3.1 迭代器原理14.3.2 迭代器使用常见问题14.4 泛型基本使用14.5 ArrayList类14.5.1 常用方法14.5.2 实现原理1…

【手写 Vue2.x 源码】第三十三篇 - diff算法-收尾+阶段性总结

一&#xff0c;前言 上篇&#xff0c;diff算法-乱序比对&#xff0c;主要涉及以下几个点&#xff1a; 介绍了乱序比对的方案介绍了乱序比对的过程分析实现了乱序比对的代码逻辑 本篇&#xff0c;diff 算法的阶段性梳理 二&#xff0c;初渲染与视图更新流程 Vue 初渲染时&…