DFS深搜与BFS广搜专题

一般搜索算法的流程框架

DFS和BFS与一般搜索流程的关系

如果一般搜索算法流程4使用的是stack栈结构(先进后出,后进先出)那么就会越搜越深。即,DFS,DFS只保存当前一条路径,其目的是枚举出所有可能性。反之,如果流程4使用的是queue队列结构(先进先出)那么就会先处理相邻的,然后再进入下一层,即,BFS

递归DFS的流程框架

 用栈的DFS和用递归的DFS区别

46. 全排列

思路

DFS + 回溯

code

#include<iostream>using namespace std;const int N = 10;int n = 3;
//最终输出
int path[N];
//记录当前使用过的数
int st[N];void dfs(int u)
{//达到阈值if (u == n){for (int i = 0; i < n; i++)printf("%d ", path[i]);puts("");return;}for (int i = 1; i <= n; i++){if (!st[i]){//存入当前内容path[u] = i;//标记当前数已使用st[i] = true;//进入下一层dfs(u + 1);//dfs结束恢复现场path[u] = 0;st[i] = false;}}
}int main()
{dfs(0);return 0;
}

DFS代码深层分析

1.首先需要两个全局定义,一个用来存储已经使用过的内容st,一个用来存储需要的内容path

2.首选处理第一个需要处理的位置位置u == 0,进入dfs中首先判断是否达到既定目标,u == n,如果没有达到,说明还没有走到尽头,继续执行

3.在进入for循环中后,首先针对u == 0需求位置,寻找合适的内容填入,for第一层循环i = =1开始进行判断,判断i == 1是否使用过,如果没有使用过,就把它加入到需求记录path[u]中,并且标记为i == 1已经使用过,本次需求位置u == 0的位置结束,进入下一个需求位置 u + 1(u == 1)

4.进入新的需求的位置后,依然判断是否达成条件,没达成继续进入for循环,此时全局记录的位置i = =1被使用过,所以来到i = = 2处使用,当本次需求位置处理完毕后 u == 1,继续进入下一个需要处理的位置 u  + 1 (u == 2)

5.当i == 3时候所有需求处理完毕,在进入循环(第四次处理的时候)触发了满足条件,直接输出了完整的path[u]内容,然后回到了上次处理,因为for中i = 3了,所以此次处理结束,回溯到上一次,并且重置条件,即 i = 2相关全部清理,然后继续i++ 为3,此时的需求依然是u + 1 = 2的情况,只不过是for为3把i = 3的情况加入到了需求位置,然后进入了下一层u + 1的循环,这样做的目的是for宗到i++保证了是一直向前的状态,再次进入到u + 1中处理的就是最后一个需求位置了,所以当查询到i = 2的时候就执行填入了,满足了所有需求输出。以此类推,输出全部可能性。

class Solution {
public:vector<vector<int>> ans;vector<bool> st;vector<int> path;vector<vector<int>> permute(vector<int>& nums) {for (int i = 0; i < nums.size(); i ++ ) st.push_back(false);dfs(nums, 0);return ans;}//nums为当前处理序列,u为当前要处理的位置void dfs(vector<int> &nums, int u){if (u == nums.size()){ans.push_back(path);return ;}for (int i = 0; i < nums.size(); i ++ )if (!st[i]){st[i] = true;path.push_back(nums[i]);dfs(nums, u + 1);st[i] = false;path.pop_back();}}};

N皇后问题

#include <iostream>using namespace std;const int N = 20;int n;
char g[N][N];
bool col[N], dg[N], udg[N];void dfs(int u)
{//u代表当前处理的行if (u == n){for (int i = 0; i < n; i ++ ) puts(g[i]);puts("");return;}//对每一行的每个列位置进行枚举处理for (int i = 0; i < n; i ++ )if (!col[i] && !dg[u + i] && !udg[n - u + i]){g[u][i] = 'Q';col[i] = dg[u + i] = udg[n - u + i] = true;dfs(u + 1);col[i] = dg[u + i] = udg[n - u + i] = false;g[u][i] = '.';}
}int main()
{cin >> n;for (int i = 0; i < n; i ++ )for (int j = 0; j < n; j ++ )g[i][j] = '.';dfs(0);return 0;
}

104. 二叉树的最大深度

思路

递归求解:
当前树的最大深度等于左右子树的最大深度加1。

时间复杂度分析:树中每个节点只被遍历一次,所以时间复杂度是 O(n)。

code

class Solution {
public:int maxDepth(TreeNode* root) {if(!root)return 0;return max(maxDepth(root->left),maxDepth(root->right)) + 1;}
};







111. 二叉树的最小深度

思路

深度只对叶子节点有效,对内部节点无效。

对于每个节点:

如果树根为空,则返回0。

如果没有子节点,说明是叶节点,则返回1;
如果有子节点,说明是内部结点,则返回子节点的深度的最小值 + 1(加上根节点这层);
时间复杂度分析:每个节点仅被遍历一次,且遍历时所有操作的复杂度是 O(1),所以总时间复杂度是 O(n)。

以本题20为计算节点高度,其左子树高度为1,右子树高度为1,取min 然后加上20这一层,20的高度为2。递推到3的时候 9的高度为1,20的高度为2,min为1,加上1为2。为最终答案

code

class Solution {
public:int minDepth(TreeNode* root) {if (!root) return 0;int res = INT_MAX;if (root->left) res = min(res, minDepth(root->left) + 1);if (root->right) res = min(res, minDepth(root->right) + 1);if (res == INT_MAX) res = 1;return res;}
};

17. 电话号码的字母组合

思路

code

//非递归方式
class Solution {
public:string chars[8] = {"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};vector<string> letterCombinations(string digits) {//判空if(digits.empty())return vector<string>();vector<string>state(1,"");for(auto u:digits){vector<string> now;//char[u - '2'] 用来确定当前号码是哪个区间取值for(auto c:chars[u - '2'])for(auto s:state)//(s + r)采用字符追加方式now.push_back(s + c);//更新外部存储     state = now;     }return state;}
};//递归方式
class Solution {
public:vector<string> ans;string strs[10] = {"", "", "abc", "def","ghi", "jkl", "mno","pqrs", "tuv", "wxyz",};vector<string> letterCombinations(string digits) {if (digits.empty()) return ans;dfs(digits, 0, "");return ans;}void dfs(string& digits, int u, string path) {if (u == digits.size()) ans.push_back(path);else {for (auto c : strs[digits[u] - '0'])dfs(digits, u + 1, path + c);}}
};

94. 二叉树的中序遍历

思路:

因为中序遍历采用【左根右】的形式,从根结点向子树深处搜索,所以使用DFS进行深度优先遍历。

code

class Solution {
public:vector<int>res;vector<int> inorderTraversal(TreeNode* root) {dfs(root);    return res;}void dfs(TreeNode* root){if(!root)return;dfs(root->left);res.push_back(root->val);dfs(root->right);}};

200. 岛屿数量

思路:Flood Fill算法

class Solution {
public:vector<vector<char>> g;int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};int numIslands(vector<vector<char>>& grid) {g = grid;int cnt = 0;for (int i = 0; i < g.size(); i ++ )for (int j = 0; j < g[i].size(); j ++ )if (g[i][j] == '1') {dfs(i, j);cnt ++ ;}return cnt;}void dfs(int x, int y) {//染色   g[x][y] = 0;for (int i = 0; i < 4; i ++ ) {int a = x + dx[i], b = y + dy[i];if (a >= 0 && a < g.size() && b >= 0 && b < g[a].size() && g[a][b] == '1')dfs(a, b);}}
};

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

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

相关文章

cloud foundry_使用“另类” Cloud Foundry Gradle插件无需停机

cloud foundry我一直在尝试编写用于将应用程序部署到Cloud Foundry的gradle插件 &#xff0c;并在上一篇文章中写了有关此插件的文章 。 现在&#xff0c;我通过使用两种方法支持将无停机时间部署到Cloud Foundry中来增强此插件&#xff1a; 自动驾驶风格部署和更常用的蓝绿色风…

懒惰学习_懒惰评估

懒惰学习最近&#xff0c;我正在编写log4j附加程序&#xff0c;并希望在自定义附加程序创建过程中使用logger记录一些诊断详细信息&#xff0c;但是log4j初始化仅在创建附加程序实例后才完成&#xff0c;因此在此阶段记录的消息将被忽略。 我感到需要在自定义附加程序中进行延…

leetcode(动态规划专题)

线性DP 53. 最大子数组和 思路 code int maxSubArray(vector<int>& nums) {//res:最后所有状态的最终Max结果//lat:当前f[i]状态的Maxint res INT_MIN, last 0;for (int i 0; i < nums.size(); i){//当前f[i]状态最大值(使用下面的状态转移方程得出)//f[i] …

leetcode(链表专题)

数组模拟链表 #include<iostream> using namespace std;const int N 100; // 单链表 // head存储链表头&#xff0c;e[]存储节点的值&#xff0c;ne[]存储节点的next指针&#xff0c;idx表示当前用到了哪个节点 int head, e[N], ne[N], idx;// 初始化 void init() {hea…

lagom cqrs_Java和Lagom的CQRS

lagom cqrs我很高兴在Chicago Java User Group上进行了讨论&#xff0c;并讨论了Lagom如何实现CQRS&#xff08;命令查询责任隔离模式&#xff09;。 值得庆幸的是&#xff0c;有一个录音&#xff0c;我还把这些幻灯片发布在slideshare上 。 抽象&#xff1a; 一旦应用程序变…

【WebRTC---源码篇】(四)WebRTC线程模型

常见的线程模型 1.为了解决频繁线程创建与销毁,在此模型中使用的线程池。在线程池创建的时候就将一些线程创建起来,以提高效率。通过控制线程数量来解决线程频繁切换。 2.一般线程与线程存在前后关系的,线程执行完毕之后生成一个新的任务(task1 , task2,task3---)插入到任…

java cuba_CUBA平台–用于快速应用程序开发的开源Java框架

java cuba传统上&#xff0c;自计算时代开始以来&#xff0c;企业软件开发自然面临着一个挑战&#xff0c;当时自然而然地&#xff0c;企业软件开发本应专注于解决实际的业务问题&#xff0c;但与此同时&#xff0c;开发人员必须在技术上花费大量时间和精力。解决方案的一面&am…

java中什么时候应用异常_生产Java应用程序中的十大异常类型-基于1B事件

java中什么时候应用异常Pareto记录原理&#xff1a;97&#xff05;的记录错误语句是由3&#xff05;的唯一错误引起的 在最新的数据整理帖子之后&#xff0c;我们收到了很多反馈和问题&#xff0c;我们发现97&#xff05;的记录错误是由10个唯一错误引起的 。 根据大众的需求&…

C++ 11 深度学习(十四)C++类

(一)综述&#xff1a;类是我们自己定义的数据类型 设计时要考虑的角度&#xff1a; 站在设计和实现的角度来考虑&#xff1b;站在使用者的角度考虑&#xff1b;父类&#xff0c;子类之间的考虑&#xff1b; &#xff08;二&#xff09;explicit 首先, C中的explicit关键字只…

手动编译 lombok_Lombok,一种编译时Java注释预处理器,可最大程度地减少代码大小...

手动编译 lombok在本文中&#xff0c;我们将看到如何在常规Java代码中使用lombok来最大程度地减少代码长度和冗余。 什么是Lombok&#xff1f; Lombok&#xff0c;一个编译时注释预处理器&#xff0c;有助于在编译时注入一些代码。 在详细介绍之前&#xff0c;我要求您应该从…

mysql超大表处理方式是_第29问:MySQL 的复制心跳说它不想跳了

问题最近年底&#xff0c;大家的数据库经常跑批量大事务&#xff0c;会发现复制突然断开&#xff0c;报错“心跳与本地信息不兼容”&#xff1a;会是什么原因&#xff1f;实验我们先来复现一下&#xff0c;再进行分析。宽油&#xff0c;做一对主从数据库&#xff1a;我们先造一…

sap 分摊分配不产生会计凭证的原因_SAP软件的物料分类账功能

物料账介绍物料分类账(Material Ledger)是SAP财务模块的重要功能之一&#xff0c;用于对标准价计价的物料进行差异处理。激活ML后&#xff0c;系统会在"工厂物料"层(或更细的层次)为每个物料建立子账簿&#xff0c;记录该物料在各个期间的数量、价值变化情况。月底运…

忽略异常_忽略已检查的异常,所有出色的开发人员都在这样做–基于600,000个Java项目...

忽略异常Github和Sourceforge上超过600,000个Java项目中的异常处理概述 Java是使用检查异常的少数几种语言之一。 它们在编译时强制执行&#xff0c;并且需要某种处理。 但是……在实践中会发生什么&#xff1f; 大多数开发人员实际上会处理任何事情吗&#xff1f; 他们怎么做…

数据结构【队列专题】

先进先出&#xff08;First In First Out&#xff0c;FIFO&#xff09;的线性序列&#xff0c;成为“队列”。 队列也是一种线性表&#xff0c;只不过它是操作受限的线性表&#xff0c;只能在两端操作&#xff1a; 一端进&#xff0c;一端出。进的一端成为队尾&#xff08;re…

oracle安装卡在create inventory_滴滴云服务器上安装Oracle12cR2单实例数据库

一、相关说明Oracle数据库是由美国甲骨文公司推出的一款优秀的关系型数据库。当前最新版为Database 19c。本文简述Oracle Database 12cR2在滴滴云主机上的安装过程。如需更权威的指导方法请参考Oracle官方安装文档。二、环境概述一台DC2云主机&#xff08;2c4g&#xff09;一个…

【WebRTC---序篇】(二)Windows平台WebRTC源码编译

需要准备的东西 (一)一个强大的梯子(懂得都懂)!!!!!!!!! (二) 下载depot_tools Windows指定地址必须在此下载 打开这个页面,找 install depot_tools 这个关键字 请把他解压到C盘,并且设置到PATH环境变量种,且让它处于最顶端。 其他需要设置的额外变量 DEPOT_TOOLS_…

商品管理后台发布商品时,规格值组合的前端交互的实现逻辑

方案1&#xff1a;先计算总行数&#xff0c;再循环填充规格值 根据每种规格值数量计算得到总行数&#xff0c;如果下图有3种规格&#xff1a;长度、重量、大小&#xff0c;规格值个数分别为&#xff1a;3、3、2,3x3x218行。 规格种类有3种&#xff0c;于是写3层嵌套递归循环填…

【WebRTC---源码篇】(五)WebRTC视频引擎

1. 视频数据的采集时间 2.视频分发器VideoBroadCaster

activiti异步执行_对基于消息队列的Activiti异步执行器进行基准测试

activiti异步执行一点历史 永无休止的一件事是&#xff0c;Activiti在某些非常大的规模的大型组织中的使用方式。 过去&#xff0c;这导致了各种优化和重构&#xff0c;其中包括异步执行器-替换旧的作业执行器。 对于未启动的用户&#xff1a;这些执行器在流程实例中处理计时器…

chrome浏览器设置网页快速到顶部和到底部的方法

鼠标移到浏览器的书签任意位置&#xff0c;点击鼠标右键添加书签&#xff0c;在添加书签的窗口输入名称和js代码&#xff0c;然后把书签移到浏览器书签栏的最左侧&#xff0c;这样每次浏览网页就可以使用快捷方式快速到底部或者顶部了。 快速到顶部的js代码&#xff1a;javascr…