Leetcode - 广度优先遍历专题

> 基础

1. 广度遍历优先是从给定的root节点开始,逐层次的向下访问各个节点;

2. 实现的方式是通过队列的先进先出,将从root节点开始的左孩子和右孩子压入到队列中,并顺序取出;

3. 由于是用队列实现,因此不存在用递归实现的方式。

下面是基本的广度遍历优先算法:

 1 def breadthFirstSearch(root):
 2     queue = []
 3     queue.append(root)
 4     while queue:
 5         node = queue[0]
 6         queue.pop(0)
 7         print (‘%d ‘ % node.data)
 8         if node.left:
 9             queue.append(node.left)
10         if node.right:
11             queue.append(node.right)

> Leetcode -

Binary Tree Level Order Traversal

Note:这是一道二叉树的广度优先遍历练习题,不同之处在于要分辨出每个Node所在的深度,并给出每个深度所有Node的集合。解题思路有两种,一种是使用两个队列,分别称之为主队列和副队列,循环主队列里的所有节点,并把所有的孩子放在副队列中。直到当主队列为空时,把副队列的所有结点赋给主队列,清空副队列,并进入到下一级深度的循环。还有一种是使用flag,在root结点后加入flag,然后每次访问到flag的时候,就意味着访问到了该深度所有的Node,并且下一个深度的所有Node都加入到了队列中,这时再加入一个flag,依此循环。这里使用第二种方法。

Answer:

 1 def levelOrder(root):
 2     if root is []:
 3         return []
 4     flag = TreeNode(65536)
 5     queue, line, res = [], [], []
 6     queue.append(root)
 7     queue.append(flag)
 8     while queue:
 9         node = queue[0]
10         queue.pop(0)
11         if node.val is not 65536:
12             line.append(node.val)
13             if node.left:
14                 queue.append(node.left)
15             if node.right:
16                 queue.append(node.right)
17         else:
18             res.append(line)
19             if not queue:
20                 return res
21             queue.append(flag)
22             line = []

 > Leetcode -

Binary Tree Level Order Traversal II

Note: 本题和上一道题的基本思路相似,唯一的不同是返回值是从最深一层的结点向root结点的方向,只要在插入res的时候位置选择在最开始就可以了。这里尝试使用上面提到的两个队列的实现方式。

Answer:

 1 def levelOrderBottom(root):
 2     if root is []:
 3         return []
 4     queue, queue2, line, res = [], [], [], []
 5     queue.append(root)
 6     while queue:
 7         node = queue[0]
 8         queue.pop(0)
 9         line.append(node.val)
10         if node.left:
11             queue2.append(node.left)
12         if node.right:
13             queue2.append(node.right)
14         if not queue:
15             res.insert(0, line)  # insert the nodes from front
16             queue, queue2, line = queue2, [], []
17     return res

> Leetcode -

Binary Tree Zigzag Level Order Traversal

Note:这道题是要按照Z字形的方式访问各个Node,我在最初写的时候犯了一个错误,我是分单双将每层的Node按照正或反的方向记录到队列中,这样会有一个问题,比如针对下面的输入[1,2,3,4,#,#,5],由于我的第二层结点是以right->left方向记录的,也就是到第二层为止输出为[1,3,2];在将下一深度的结点入队的时候,我就是先访问的3,后访问的2,因此5先进入,4后进入,这样第三级由于是left->right输出的,我的最终输出就是[[1], [3, 2], [5, 4]],而正确的输出其实是[[1], [3, 2], [4, 5]]。其实这个问题可以和之前的很类似,只是在将line压入res的时候,隔行做一下python list的反转就可以了。

Answer:

 1 def zigzagLevelOrder(root):
 2     if root is []:
 3         return []
 4     flag = TreeNode(65536)
 5     queue, line, res = [], [], []
 6     direction = 0
 7     queue.append(root)
 8     queue.append(flag)
 9     while queue:
10         node = queue[0]
11         queue.append(0)
12         if node.val is not 65536:
13             line.append(node.val)
14             if node.left:
15                 queue.append(node.left)
16             if node.right:
17                 queue.append(node.right)
18         else:
19             if direction % 2 == 0:
20                 res.append(line)
21             else:
22                 res.append(line[::-1])
23             if not queue:
24                 return res
25             queue.append(flag)
26             line = []
27             direction += 1        
时间: 2024-10-24 15:01:51

Leetcode - 广度优先遍历专题的相关文章

LeetCode 单链表专题 (一)

目录 LeetCode 单链表专题 <c++> \([2]\) Add Two Numbers \([92]\) Reverse Linked List II \([86]\) Partition List \([82]\) Remove Duplicates from Sorted List II \([61]\) Rotate List \([19]\) Remove Nth Node From End of List LeetCode 单链表专题 <c++> \([2]\)

浅谈数据结构之图的邻接表深度和广度优先遍历(九)

邻接矩阵是一种不错的图存储结构,但是我们发现,对于边数相对较少的图,这种结构是存在对存储空间的极大浪费的.我们知道,顺序存储结构存在预先分配内存可能造成空间浪费的问题,于是引出了链式存储的结构.同样的,我们也可以考虑对边或弧使用链式存储的方式来避免空间浪费的问题.因此,对于图的存储结构,我们同样引入了一种数组与链表相组合的存储方法,我们一般称之为邻接表. 邻接表的处理方法是这样的:(1).图中顶点用一个一维数组存储,当然,顶点也可以用单链表来存储,不过数组可以较容易的读取顶点的信息,更加方便:另

树的深度优先遍历和广度优先遍历

1 import java.util.ArrayDeque; 2 3 public class BinaryTree { 4 static class TreeNode{ 5 int value; 6 TreeNode left; 7 TreeNode right; 8 9 public TreeNode(int value){ 10 this.value=value; 11 } 12 } 13 14 TreeNode root; 15 16 public BinaryTree(int[] ar

二叉树 广度优先遍历

/** * 广度优先遍历 * **/ public void BreadthFirstTreeWalk(BSTreeNode<T> root, Action<BSTreeNode<T>> func) { if (root == null) { return; } List<BSTreeNode<T>> processQueue = new List<BSTreeNode<T>>(); processQueue.Add(ro

图---广度优先遍历

1.解决问题:判断一幅图中 从顶点S到顶点V之间是否有一条路径---Dijkstar算法的基础(计算出S--V点中最短路径) 1.使用队列(FIFO)先进先出原则 存储与顶点S相距 N条边的点,直到遍历到V点上  不同于深度优先遍历 不需要进行递归 因此 BFS无法判断图中是否有环的 判断出一个有向图是否有环的是:a.最短路径有向图最短路径Dijkstra不一定能够判断有环,除非Visted数字记录0(false),1(已经访问)2(再一次重复访问): b.括扑排序:通过入度0之后记录顶点数与原

二叉树遍历(前序、中序、后序、层次、深度优先、广度优先遍历)

二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有深度遍历和广度遍历,深度遍历有前序.中序以及后序三种遍历方法,广度遍历即我们平常所说的层次遍历.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁,而对于广度遍历来说,需要其他数据结构的支撑,比如堆了.所以,对于一段代码来说,可读性有时候要比代码本身的效率要重要的多. 四种主要的遍历思想为: 前序遍历:根结点 ---> 左子树 ---> 右子树 中序遍历:左子

如何实现广度优先遍历(BFS)

BFS过程: 一:访问顶点V,并标记V为已经访问 二:顶点V入队列 三:如果队列非空,进行执行,否则算法结束 四:出队列取得对头顶点u,如果顶点未被访问,就访问该顶点,并标记该顶点为已经访问 五:查找u的第一个邻接节点w 六:如果w不存在,则转到步骤三,否则循环执行 a. 如果w没有被访问过,则先把w入队列 b.查找顶点u的下一个邻接节点,记为w,并转到步骤六 上图使用BFS访问顺序为: A BEDC 队列的变化过程如下: A B BE ED D C 代码如下: #include<iostrea

Dungeon Master UVA 532 (三维空间的广度优先遍历)

说说: 其实这道题就是一道广度优先遍历求最短路径的简单题目.但是可能今晚状态不太好,开始一直想当然地就按深度优先遍历去写了.然后测试数据又刚好能通过,结果就特别地纠结.不过总的来说,这道题是非常简单的.至于代码的话,后来写得烦起来了,可能看起来有点凌乱QAQ 源代码: #include <stdio.h> #include <string.h> #define MAX 30+5 typedef struct{ int x; int y; int z; int dis; }NODE;

树的深度优先与广度优先遍历

简述树的深度优先及广度优先遍历算法,并说明非递归实现. 原题出自百度的笔试: 当时我看到这个题目的时候,已经完全记不得非递归算法该怎么实现了,后来查阅了一下,要用到两个辅助的数据结构: 深度优先遍历--->栈: 广度优先遍历--->队列: 这里以二叉树为例来实现. import java.util.ArrayDeque; public class BinaryTree { static class TreeNode{ int value; TreeNode left; TreeNode rig