1.2 Breadth First Search

什么时候应该使用BFS?

图的遍历 Traversal in Graph

  • 层级遍历 Level Order Traversal

  • 由点及面 Connected Component :判断连通性

  • 拓扑排序 Topological Sorting

    最短路径 Shortest Path in Simple Graph • 仅限简单图求最短路径

    即,图中每条边长度都是1,且没有方向

3.1 二叉树上的宽搜 BFS in Binary Tree

Binary Tree Level Order Traversal

#V1: deque: double queue
from collections import deque

class Solution:
    """
    @param root: A Tree
    @return: Level order a list of lists of integer
    """
    def levelOrder(self, root):
        if root is None:
            return []

        queue = deque([root])
        result = []
        while queue:
            level = []
            size = len(queue)
            for _ in range(size): #queue长度变化不会有影响,因为range()是生成一个固定的值
                node = queue.popleft()
                level.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            result.append(level)
        return result

3.2 Binary Tree Serialization (M+Y)

什么是序列化?

将“内存”中结构化的数据变成“字符串”的过程

序列化:object to string

反序列化:string to object

常用的一些序列化手段:

  • XML

  • Json

  • Thrift (by Facebook)

  • ProtoBuf (by Google)

序列化算法 一些序列化的例子:

  • 比如一个数组,里面都是整数,我们可以简单的序列化为”[1,2,3]”

  • 一个整数链表,我们可以序列化为,”1->2->3”

  • 一个哈希表(HashMap),我们可以序列化为,”{\”key\”: \”value\”}”

二叉树序列化

  • 二叉树如何序列化? 你可以使用任何你想要用的方法进行序列化,只要保证能够解析回来即可。

    LintCode 采用的是 BFS 的方式对二叉树数据进行序列化,这样的好处是,你可以更为容易的自己画出 整棵二叉树。

3.3 图上的宽搜 BFS in Graph

Graph Valid Tree

图的遍历(由点及面) 条件1:刚好N-1条边 条件2:N个点连通

灌水法

dictionary 建立邻接表,queue做BFS用,visited为hashset,快速查找。 先判断边数是否为节点数-1,再判断是否所有点可以访问到。两个条件可以看是否无环。

Clone Graph

3.4 拓扑排序

Topological Sorting

Course Schedule裸拓扑排序

找出所有拓扑排序:dfs

Sequence Reconstruction

判断是否有且仅有一个能从 seqs重构出来的序列,并且这个序列是org

(判断是否只存在一个拓扑排序的序列 只需要保证队列中一直最多只有1个元素即可)

3.5 BFS in Matrix

矩阵 vs 图

图 Graph N个点,M条边 M最大是 O(N^2) 的级别 图上BFS时间复杂度 = O(N + M) or O(M)

• 说是O(M)问题也不大,因为M一般都比N大 所以最坏情况可能是 O(N^2)

矩阵 Matrix R行C列 RC个点,RC2 条边(每个点上下左右4条边,每条边被2个点共享)。 矩阵中BFS时间复杂度 = **O(R C)**

Number of Islands

图的遍历(由点及面)

坐标变换数组

int[] deltaX = {1,0,0,-1};

int[] deltaY = {0,1,-1,0};

问:写出八个方向的坐标变换数组?

int[] deltaX = {1,0,0,-1,1,1,-1,-1};

int[] deltaY = {0,1,-1,0,1,-1,1,-1};

Zombie in Matrix

1 代表僵尸,0 代表人类(数字 0, 1, 2)。僵尸每天可以将上下左右最接近的人类感染成僵尸,但不能穿墙。将所有人类感染为僵尸需要多久,如果不能感染所有人则返回 -1

Smallest Rectangle Enclosing Black Pixels

Word Ladder

(简单图最短路径)

给出两个单词(startend)和一个字典,找出从startend的最短转换序列,输出最短序列的长度。

变换规则如下:

  1. 每次只能改变一个字母。

  2. 变换过程中的中间单词必须在字典中出现。(起始单词和结束单词不需要出现在字典中)

Word Ladder II

给出两个单词(startend)和一个字典,找出所有从startend的最短转换序列。

变换规则如下:

  1. 每次只能改变一个字母。

  2. 变换过程中的中间单词必须在字典中出现。

总结 Conclusion

  • 能用 BFS 的一定不要用 DFS(除非面试官特别要求)

  • BFS 的两个使用条件

    • 图的遍历(由点及面,层级遍历)

    • 简单图最短路径

  • 是否需要层级遍历

    • size = queue.size()

  • 拓扑排序必须掌握!

  • 坐标变换数组

    • deltaX, deltaY • inBound

Last updated