LeetCode刷题之BFS和DFS

广度优先搜索(BFS)

主要用于树的层序遍历或图的最短路径寻找,主要使用队列queue来完成。

①树的层序遍历:使用队列保存未被检测的结点,结点按照宽度优先的次序被访问和进出队。

②有向无环图的最短路径查找:由于有向无环图的某个节点的next节点可能会与另一个节点的next节点重复,所以我们需要记录已访问过的节点

//根节点与目标节点之间的最短路径长度
int BFS(Node root, Node target) {
    Queue<Node> queue;  // 用来存放节点的队列
    Set<Node> used;     // 用来存放已经使用过的节点
    int step = 0;       // 步长

    //1:初始化
    add root to queue;
    add root to used;

    //2:开始进行BFS
    while (queue is not empty) {
        step = step + 1;

        //队列中已经存放的节点个数
        int size = queue.size();
        for (int i = 0; i < size; ++i) {
            Node cur = the first node in queue;
            return step if cur is target;
            for (Node next : the neighbors of cur) {
                if (next is not in used) {
                    add next to queue;
                    add next to used;
                }
            }
            remove the first node from queue;
        }
    }
    return -1;          // there is no path from root to target
}

深度优先搜索(DFS)

一直往深处走,直到找到解或者走不下去为止,主要用于树的遍历(前序遍历,中序遍历,后序遍历)或者图的搜索问题或者回溯算法问题。

①树的遍历:一直向叶子节点遍历,直至遇到叶子节点表示此根节点到这个叶子节点的路径已经访问完,需要访问根节点到下一个叶子节点的路径。(当然遍历顺序主要取决于遍历的方式,比如前序遍历(根左右)、后序遍历(左根右)、后序遍历(左右根))

②图的搜索问题:上面我们使用了BFS来解决图的最短路径问题,同时我们也可以使用DFS来实现图的最短路径寻找。在这里我们分别提供递归版模板和用stack的迭代版模板:

递归

boolean DFS(Node cur, Node target, Set<Node> visited) {
    return true if cur is target;
    for (next : each neighbor of cur) {
        if (next is not in visited) {
            add next to visted;
            return true if DFS(next, target, visited) == true;
        }
    }
    return false;
}

非递归

boolean DFS(int root, int target) {
    Set<Node> visited;
    Stack<Node> s;
    add root to s;
    while (s is not empty) {
        Node cur = the top element in s;
        return true if cur is target;
        for (Node next : the neighbors of cur) {
            if (next is not in visited) {
                add next to s;
                add next to visited;
            }
        }
        remove cur from s;
    }
    return false;
}

回溯法:回溯法使用DFS的策略来寻找所有可行解或者最优解,也就是回溯法的所有解可以构成一个解空间树或者解空间图,所以对于这个解空间树或图,我们就使用DFS策略了

//choicelist:表示可以进行选择的列表,相当于树中可选用左节点还是右结点
//track:表示为决策路径,相当于在树中为根节点到某个叶子节点的路径
//result:表示存放根节点到所有叶子节点的所有路径
backtrack(choicelist,track,result)
{
	if(track is ok)result.push(track);
	else{
		for choice in choicelist:
			//choose过程:选择一个choice加入track,相当于在树中选择一个节点加入路径
			backtrack(choices,track,result);//进入下一步决策
			//unchoose过程:从track中撤销上面的选择,相当于在树中移除上一次选择的节点
	}
}

应用与风险:

1)DFS多用于连通性问题因为其运行思想与人脑的思维很相似,故解决连通性问题更自然。

2)BFS多用于解决最短路问题,其运行过程中需要储存每一层的信息,所以其运行时需要储存的信息量较大,如果人脑也可储存大量信息的话,理论上人脑也可运行BFS。

3)多数情况运行BFS所需的内存会大于DFS需要的内存(DFS一次访问一条路,BFS一次访问多条路)

4)风险:DFS容易爆栈(栈不易”控制”),BFS通过控制队列可以很好解决”爆队列”风险。

原文链接:https://blog.csdn.net/qq_43152052/article/details/99229105

原文地址:https://www.cnblogs.com/xym4869/p/12575831.html

时间: 2024-10-03 15:55:28

LeetCode刷题之BFS和DFS的相关文章

【leetcode刷题笔记】Permutations II

Given a collection of numbers that might contain duplicates, return all possible unique permutations. For example,[1,1,2] have the following unique permutations:[1,1,2], [1,2,1], and [2,1,1]. 题解:跟Permutation差不多,只是这次会有重复的元素,如下图所示,如果只用DFS的话就会产生重复的排列: 上

【leetcode刷题笔记】Sum Root to Leaf Numbers

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. An example is the root-to-leaf path 1->2->3 which represents the number 123. Find the total sum of all root-to-leaf numbers. For example, 1 / 2 3 T

leetcode 刷题之路 63 Binary Tree Zigzag Level Order Traversal

Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). For example: Given binary tree {3,9,20,#,#,15,7}, 3 / 9 20 / 15 7 return its zig

leetcode 刷题之路 64 Construct Binary Tree from Inorder and Postorder Traversal

Given inorder and postorder traversal of a tree, construct the binary tree. Note: You may assume that duplicates do not exist in the tree. 给出二叉树的中序遍历和后序遍历结果,恢复出二叉树. 后序遍历序列的最后一个元素值是二叉树的根节点的值,查找该元素在中序遍历序列中的位置mid,根据中序遍历和后序遍历性质,有: 位置mid以前的序列部分为二叉树根节点左子树中

【leetcode刷题笔记】Longest Consecutive Sequence

Given an unsorted array of integers, find the length of the longest consecutive elements sequence. For example,Given [100, 4, 200, 1, 3, 2],The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4. Your algorithm should run in

【leetcode刷题笔记】Remove Duplicates from Sorted Array II

Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For example,Given sorted array A = [1,1,1,2,2,3], Your function should return length = 5, and A is now [1,1,2,2,3]. 题解: 设置两个变量:右边kepler和前向游标forward.如果当前kepeler所指的元素和

【leetcode刷题笔记】Restore IP Addresses

Given a string containing only digits, restore it by returning all possible valid IP address combinations. For example:Given "25525511135", return ["255.255.11.135", "255.255.111.35"]. (Order does not matter) 题解:深度优先搜索.用resul

【leetcode刷题笔记】Path Sum

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. For example:Given the below binary tree and sum = 22, 5 / 4 8 / / 11 13 4 / \ 7 2 1 return true, as t

【leetcode刷题笔记】Insertion Sort List

Sort a linked list using insertion sort. 题解:实现链表的插入排序. 要注意的地方就是,处理链表插入的时候尽量往当前游标的后面插入,而不要往前面插入,后者非常麻烦.所以每次利用kepeler.next.val和head.val比较大小,而不是kepeler.val和head.val比较大小,因为如果用后者,要把head指向的节点插入到kepeler指向的节点的前面,如果kepeler指向的节点是头结点,就更麻烦了. 代码如下: 1 /** 2 * Defi