BFS和DFS
文章平均质量分 57
bfs dfs
山顶夕景
实践出真知
展开
-
DFS&剪枝复习
1.使用场景输入数据:如果是递归数据结构,如单链表,二叉树,集合,则一定可以用DFS;如果是非递归数据结构,如一维数组,二维数组,字符串,图,则概率小一点。状态转换图:树或图求解目标:必须要走到最深(如树,必须走到叶结点)才能得到一个解,这种情况适合用DFS2.DFS思考的步骤1.是求路径条数,还是路径本身(或动作序列)?DFS最常见的三个问题,求可行解的总数,求一个可行解,求所有可行解。(a)如果是路径条数,则不需要存储路径(b)如果是求路径本身,则要用一个数组path[]存储路径。和B原创 2021-01-14 20:52:37 · 792 阅读 · 0 评论 -
【leetcode994】腐烂的橘子(BFS)
首先将所有烂橘子入队,然后常规BFS遍历,注意while的截止条件除了队列为空,新鲜橘子数量大于0(没新鲜橘子也没必要继续遍历,保证时间计算的正确性),这两者一个不满足就可以停止每分钟进行一次【腐烂扩散】,使用BFS对二维图进行遍历,注意和二叉树的层次遍历不一样(二叉树则是只有一个根节点,这里可能有多个腐烂橘子-根节点)。auto [x, y] = q.front()是C++17引入的新语法,结构化绑定,可以从数组、元组或结构体中一次性解包多个值,并将他们绑定到多个变量上,比如这里就是声明了x和y变量,原创 2024-02-16 11:34:41 · 528 阅读 · 1 评论 -
【LeetCode199】二叉树的右视图(层次遍历或DFS)
二、思路最直观的是层次遍历,然后存入每层第一个元素到结果列表中如果用dfs,(根节点,右子树,左子树)的顺序进行访问节点;按照题目规则只会在每层中抽取最右侧的一个节点,如果当前的深度等于结果数组的size,则这是第一次访问该层,且当前节点满足条件。三、代码原创 2023-05-28 15:18:00 · 205 阅读 · 0 评论 -
【LeetCode513】找树左下角的值(dfs)
一、题目二、思路dfs遍历二叉树,其实可以直接用前序遍历,注意为了找到最早出现的最深的左节点,所以需要先遍历左子树,再遍历右子树。为了满足“最深”的条件,需要比较当前depth和maxdepth值,进行更新maxdepth。其实题目要求找到最底层的最左边的节点,没指定一定是左孩子哈哈,如果没有左孩子,只有右孩子,那该右孩子也是最左边的节点。三、代码/** * Definition for a binary tree node. * struct TreeNode { * i原创 2022-04-15 12:33:24 · 851 阅读 · 0 评论 -
【LeetCode剑指offer12】矩阵中的路径(dfs回溯)
文章目录一、题目二、思路三、代码一、题目二、思路递归参数: 当前字符在矩阵 board 中的行索引 i 和列索引 j ,当前目标字符(匹配的)在目标字符串 word 中的索引 k 。终止条件:返回 false : (1) 行索引或列索引越界 (2) 当前矩阵字符与目标字符不同;返回 true : 当前目标字符(匹配的)在目标字符串 word 中的索引 k = len(word) - 1 ,即目标字符串 word 已全部匹配;递归过程:标记访问过字符: 将 board[i][j] 修改为 ‘/原创 2022-04-03 10:17:26 · 812 阅读 · 0 评论 -
【LeetCode108】将有序数组转换为二叉搜索树(中序遍历)
一、题目二、思路给定的升序数组,其实就是BST的中序遍历数组,只是给定一棵二叉树的中序遍历数组,并不能确定一棵二叉树,但是题目要求是严格平衡的二叉搜索树,所以可以选择升序序列的中间元素作为当前的根结点元素。三、代码/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode()原创 2022-02-21 11:47:16 · 963 阅读 · 0 评论 -
【LeetCode542】01矩阵(BFS)
一、题目中等题。提示:m == mat.lengthn == mat[i].length1 <= m, n <= 1041 <= m * n <= 104mat[i][j] is either 0 or 1.mat 中至少有一个 0二、思路(1)其实和上一题(【LeetCode286】墙与门(BFS))非常相似,这题的0就相当于286题的门,但是本题是可能存在多个门“堆”在一起(多个0)的情况,首先将0加入队列,从每个0开始一圈圈向1用BFS扩散,可以设置二原创 2022-01-22 21:57:23 · 950 阅读 · 0 评论 -
【LeetCode剑指offer13】机器人的运动范围(BFS)
一、题目二、思路(1)求数位之和就while循环,每次循环求余;(2)bfs或者dfs都可以,如果用bfs则用到队列,遍历时为了防止重复遍历和遇到不合法的格子,在push入队列之前进行判断。三、代码class Solution {private: vector<pair<int, int>>directions{{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; //获取数位之和 int getNum(int x){原创 2022-01-22 16:30:27 · 789 阅读 · 0 评论 -
【LeetCode286】墙与门(BFS)
一、题目给定一个 m × n 的二维网格,网格中有以下三种可能的初始化值:-1 表示墙或是障碍物0 表示一扇门INF 无限表示一个空的房间。然后,我们用 2312^{31}231 - 1 = 2147483647 代表 INF。你可以认为通往门的距离总是小于 2147483647 的。你要给每个空房间位上填上该房间到 最近门的距离,如果无法到达门,则填 INF 即可。样例1:输入:[[2147483647,-1,0,2147483647],[2147483647,2147483647,21原创 2022-01-21 21:51:59 · 1470 阅读 · 0 评论 -
【LeetCode752】打开转盘锁(BFS)
一、题目中等题。二、思路每个节点有8个孩子节点,如题目给的第二个测试用例,start=0000时,4个位置分别可以向上转or向下转,得到1000、9000、0100、0900等8种情况。即这是一棵八叉树。即求解从start数字到target的最短路径。为了找到最小旋转次次数,利用BFS逐层查找,遇到target则返回树高度(层数)。需要关注两个点:(1)防止走回头路,如从0000到1000,之后不能回到0000,不然就死循环了。所以需要借助哈希表。(2)需要跳过died number,这也是原创 2022-01-21 17:33:49 · 831 阅读 · 0 评论 -
【LeetCode1254】统计封闭岛屿的数目(dfs)
一、题目二、思路和 【LeetCode200】岛屿数量(求连通分量个数) 的区别是:(1)1和0对应 水域和陆地,刚好和之前相反;(2)200题中边界上的陆地也算岛屿,但本题不算。本题一定要上下左右被水(1)包围的才是岛屿。所以可以先将边界周围的岛屿“淹没”,然后再和200题一样dfs,前者操作用的dfs和后者一毛一样,只不过在后者dfs时的双层for内要统计岛屿数量,即连通分量num。三、代码class Solution {private: vector<pair<原创 2022-01-18 20:50:18 · 873 阅读 · 0 评论 -
【LeetCode1020】飞地的数量
一、题目提示:1 <= A.length <= 5001 <= A[i].length <= 5000 <= A[i][j] <= 1所有行的大小都相同二、思路从4条边界进行遍历,即遇到边界上的1就递归遍历,把边界上的都为1的连通分量改成数字2,dfs搞完后,就遍历一遍二维数组,剩下的1即所求的飞地数量。方法和 【LeetCode130】被围绕的区域(dfs)基本一致。三、C++代码class Solution {private: ve原创 2022-01-18 19:51:12 · 747 阅读 · 0 评论 -
【LeetCode417】太平洋大西洋水流问题
文章目录一、题目二、思路三、代码一、题目二、思路(1)找出从太平洋出发的水所能到达的点:(2)找出所有从大西洋出发的水能到达的点(从低到高):(3)找出1和2的重合点:(1)其实满足条件的点中,其从对应的海洋到该点的路线可能是有多条的,但是注意我们只需要找到满足条件的点,而不是找出所有路线。所以可以遍历到当前节点时就用canReach数组进行标记(标记为true,确定遍历过),这种情况就是找到一条路线即可。(2)ps:一开始两个for循环的边界的col和row写反了,导致heap o原创 2022-01-18 16:55:48 · 820 阅读 · 0 评论 -
【LeetCode130】被围绕的区域(dfs)
一、题目提示:m == board.lengthn == board[i].length1 <= m, n <= 200board[i][j] 为 ‘X’ 或 ‘O’二、思路逆向思维:要把被X包围的所有O,都替换为X,就可以先把没被X包围的O找出来(这些O最后结果不会改变),可以通过遍历边界上的O,对其进行dfs找到这些O的连通分量。你肯定会问,会不会有存在不是上面情况,并且没被X包围的呀——不存在的,不在边界O的连通分量,那自然是在“内部”了,即被X包围。(1)从边界原创 2022-01-17 21:42:35 · 685 阅读 · 0 评论 -
【LeetCode695】岛屿的最大面积(FloodFill 算法,dfs)
一、题目二、思路就是在leetcode200 岛屿数量 的基础上进行修改,加一个max和cur_max的比较判断和更新,特别注意无论是否更新了,最后别漏了重置cur_max = 0;。三、代码class Solution {private: vector<pair<int,int>>directions{{0,1},{0,-1},{1,0},{-1,0}}; int num;//岛屿个数 int max = 0; int cur_max原创 2022-01-17 19:14:52 · 811 阅读 · 0 评论 -
【LeetCode841】钥匙和房间(dfs)
一、题目提示:n == rooms.length2 <= n <= 10000 <= rooms[i].length <= 10001 <= sum(rooms[i].length) <= 30000 <= rooms[i][j] < n所有 rooms[i] 的值 互不相同二、思路dfs基础题。以测试用例2为栗子画了个图:像右边,3号为父结点和孩子结点之间是不连接的,因为0号房间已经遍历过了。一开始用版本一的代码有些测试用例没过原创 2022-01-17 17:22:40 · 785 阅读 · 0 评论 -
【LeetCode494】目标和(暴搜dfs或dp)
一、题目提示:1 <= nums.length <= 200 <= nums[i] <= 10000 <= sum(nums[i]) <= 1000-1000 <= target <= 1000二、思路暴搜dfs基础题。(1)一开始很傻把k==nums.size())和cur_res == target两个条件写一块判断了,其实要分开判断,因为即使cur_res == target不满足,最后也是要return的;(2)注意在dfs中的原创 2022-01-16 20:56:27 · 623 阅读 · 0 评论 -
【LeetCode133】克隆图(dfs和unordered_map)
一、题目示例1:输入:adjList = [[2,4],[1,3],[2,4],[1,3]]输出:[[2,4],[1,3],[2,4],[1,3]]解释:图中有 4 个节点。节点 1 的值是 1,它有两个邻居:节点 2 和 4 。节点 2 的值是 2,它有两个邻居:节点 1 和 3 。节点 3 的值是 3,它有两个邻居:节点 2 和 4 。节点 4 的值是 4,它有两个邻居:节点 1 和 3 。示例2:输入:adjList = [[]]输出:[[]]解释:输入包含一个空列表原创 2022-01-16 16:31:33 · 715 阅读 · 0 评论 -
【LeetCode138】复制带随机指针的链表(dfs+哈希unordered_map)
一、题目示例1:输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]示例2:输入:head = [[1,1],[2,1]]输出:[[1,1],[2,1]]示例3:输入:head = [[3,null],[3,0],[3,null]]输出:[[3,null],[3,0],[3,null]]示例4:输入:head = []输出:[]解释:给定的链表为空原创 2022-01-10 22:05:58 · 904 阅读 · 1 评论 -
【网易算法笔试】树上摘樱桃
题目有一棵二叉树,树上的叶子节点定义为“樱桃”。现在需要找出树上有多少个满足如下子结构的“樱桃”串,即一串上刚好有两颗“樱桃”。比如如下的一棵树,红框标示的有两个符合要求的结构,答案就是2:又比如下面的这颗树,没有任何符合要求的子结构,则答案是0:输入描述:第一行两个正整数m, n,空格分开,分别代表总共有树上有多少个节点,和树上有多少条边,2<=m<=100, 1<=n<=100。下面有n行,每行为3个部分,用空格分割,第一个数字为某非叶子节点的id, 第二个为该原创 2022-01-04 21:15:19 · 1753 阅读 · 3 评论 -
【网易算法提前批】平分物品
文章目录一、题目描述二、解题思路三、C++代码Reference一、题目描述现在有n个物品,每一个物品都有一个价值,现在想将这些物品分给两个人,要求这两个人每一个人分到的物品的价值总和相同(个数可以不同,总价值相同即可),剩下的物品就需要扔掉,现在想知道最少需要扔多少价值的物品才能满足要求分给两个人。要求:时间复杂度O(3n)O(3^n)O(3n),空间复杂度O(n)O(n)O(n)输入描述第一行输入一个整数 T,代表有 T 组测试数据。对于每一组测试数据,一行输入一个整数 n ,代表物品的个数原创 2022-01-04 11:50:00 · 1643 阅读 · 2 评论 -
【LeetCode22】括号生成(DFS回溯剪枝-多种解法)
文章目录1.题目2.常规的遍历3.剪枝处理4.根据条件判断是否遍历5.其他写法1.题目2.常规的遍历对于这种要找到所有符合情况的,先明白二叉树是咋样的(树高为2n,因为n为括号对数,一对有左右两个括号),再进行剪枝获得满足要求的情况:遍历上面二叉树的代码如下:class Solution {private: vector<string>ans;public: vector<string> generateParenthesis(int n) {原创 2021-04-12 17:29:48 · 769 阅读 · 0 评论 -
【LeetCode200】岛屿数量(求连通分量个数)
1.题目2.思路(1)本质就是用dfs遍历求图的连通分量个数(之前做过类似的——【LeetCode79】单词搜索)dfs注意base case和递归体。base case是非1字符和非网格外位置,如果“判断是否网格内”写在base case时后面的递归前就不用判断是否在网格内了;如果没写在base case,后面递归前就判断。(2)如果不用这个directions的vector方向数组,就写4个dfs。(3)为了防止重复遍历连通分量,需要将遍历过1的位置做标记——可以另外开个二维数组了,直接在原创 2021-04-06 22:26:32 · 1148 阅读 · 0 评论 -
【LeetCode17】电话号码的字母组合(DFS回溯)
1.题目2.思路之前做的【HJ21】简单密码破解(字符转换)也涉及手机按键字符是将字符分为两种:三个字母一组,四个字母一组,再利用ASCII码找规律。为了后面深搜方便遍历,这题我们利用map<char,string>将数字字符和对应的按键字母对应起来。dfs遍历,如输入digits为“23”时,这颗遍历树分别(指向)遍历数字2对应的三个字母a、b、c,该三个分支的每个分支,又指向数字3所对应的3个字母d、e、f。3.代码class Solution {private:原创 2021-02-22 11:33:57 · 743 阅读 · 0 评论 -
【LeetCode128】最长连续序列(unordered_map+dfs-记忆化搜索)
1.题目2.法一:用sort初级解法:用sort排序和用unique去重后for循环遍历一遍数组,如果当前和上一个数字之差为1,则count累加1;如果当前数字和上一个数字之差不为1,则重新设count为1计算。为啥要去重呢:题目说的数字连续的最长序列,如第二个组测试用例,0012345678,就不包括重复的0了,而是从0到8计数。复杂度:没达到O(n)的时间复杂度——因为用了sort排序,时间复杂度是O(nlog n)。 class Solution {public: int lon原创 2021-02-14 16:42:36 · 1615 阅读 · 3 评论 -
【LeetCode79】单词搜索(DFS回溯综合)
1.题目2.思路(1)可以复习【1091】三维&二维BFS&复习这篇,在这篇的方向移动处理是设置2个数组(x轴、y轴),也可以换成2维vector数组,也可以vector<pair<int,int>>即对于每个pair对的元素引用是first,second。【LeetCode5665】从相邻元素对还原数组。(2)只要有一处返回true,就能说明二维数组中能找到对应的单词;(3)二维visited数组和board数组大小相同(在exist函数里就要设置好大小原创 2021-02-10 23:04:40 · 753 阅读 · 0 评论 -
【LeetCode5665】从相邻元素对还原数组(STL&DFS)
文章目录1.题目2.思路3.代码4.不用dfs版本1.题目2.思路(1)不可以像以前用vector数组存储邻接表(否则会报出下面的错误)——因为数组的元素可能是负数!!!并木有vector<int,vector<int>>,所以使用map<int,vector<int>>adj存储邻接表,所以后面dfs用到的vis访问数组也是map<int,bool>类型而非vector<bool>vis。用undered_map显然比m原创 2021-02-01 01:24:25 · 837 阅读 · 1 评论 -
【LeetCode39】组合总和(回溯法)
1.题目2.思路由于要求出所有情况,而非求出可能的情况数,所以不使用动态规划,要用回溯法。(1)由于每个数字可以重复选择,所以递归的即不选择当前数的dfs的参数index不用加1。(2)由于传参的candidates不用传值,而用传值,试了下时间相差了30%。3.代码class Solution {public: vector<vector<int>>ans; //int n=candidates.size(); vector<int&原创 2021-01-30 23:52:47 · 775 阅读 · 0 评论 -
【LeetCode46】全排列(DFS)
1.题目2.思路DFS遍历,回溯。vector<bool>hashtable(nums.size(),false);这句不要漏了,虽然vector型初始化后数值默认为0即false,但这里也要初始化大小,不然会报错。可以回顾n皇后 暴力&回溯这篇,基本一样的题。3.代码class Solution {public: vector<vector<int> >result; vector<int>p;//装入的一组原创 2021-01-27 23:58:47 · 738 阅读 · 0 评论 -
【1076】Forwards on Weibo (图BFS)
1.题目https://pintia.cn/problem-sets/994805342720868352/problems/994805392092020736微博转发背景,给出N个用户的关注情况(关注的人有哪些)和转发层数上限L,用最初发布消息的用户编号进行查询,求在转发层数上限内消息最多会转发的用户数。2.思路同一层可以有多个粉丝进行转发,所以显然用BFS合适。不过写的时候出现了是三个傻逼BUG,实在该打!(1)在输入点的坐标的for循环时候忘记结点的编号是1~N,而不是0,所以不能习惯地原创 2021-01-20 23:59:30 · 676 阅读 · 0 评论 -
【1091】三维&二维BFS&复习
1.题目https://pintia.cn/problem-sets/994805342720868352/problems/994805375457411072给出一个2.思路由于是三维矩阵,需要3.代码#include<iostream>#include<stdio.h>#include<stdlib.h>#include<queue> using namespace std; //利用BFS遍历,找到卒中核心块struct no原创 2021-01-15 21:38:27 · 805 阅读 · 3 评论 -
【1103】Integer Factorization (DFS)
1.题目https://pintia.cn/problem-sets/994805342720868352/problems/994805364711604224给出正整数N,K,P,求N由K个整数的分别的P次方的和的情况,如果有多种情况则选择底数和最大的方案。举例:169 5 2输出:159=6^ 2 + 6^ 2+6^ 2+6^ 2+5^ 22.思路第3、4个测试点没过,只拿了26/30分呜呜呜。大致思路是对的:(1)开一个vector数组fac存0^ p ,1^ p… i ^ p.(原创 2021-01-15 15:47:27 · 702 阅读 · 0 评论