Chapter 4: Trees and Graph
Tree 和 Graph 本质上是刻画事物之间的关系的data structure,根据关系的特性决定使用Tree还是Graph。无论输入给定了什么数据结构,只要路径空间是二维的,我们就应该使用这两种数据结构
知识解析
4.4 Graph的表述
类似于Tree,Graph主要用于描述事物之间的关系,只要每个节点的parent可能有多个(常见),或者有可能存在cycle,就必须用graph而不是tree来解决。Graph由Vertices (点)和 Edges (边) 组成
4.4.1 用 object GraphNode代表vertex,用 array of GraphNode代表从vertex出发的edges指向的children node, 即
class GraphNode:
def __init__(val):
self.val = val
self.children: List[GraphNode] = [] # array of GraphNode4.4.2 【基准表述】用 2d array 的index (或者hash的key)代表vertex的id,用subarray代表edges指向的children ids, 即
edge_matrix = [
[ 1, 2 ], # children ids for node 0
[ 2 ], # children ids for node 1
[ ], # children ids for node 2
]
# or use a hash
vertice_children_map = {
0: [1,2],
1: [2]
}4.4.3 用 2d array 的index 代表vertex的id,用subarray中value为1的index来代表children id,即
4.4.4 用 0 ~ n 的整数代表vertex的id, 用array of pairs代表所有的edges, 每个pair代表指出和指入的vertex id,一般先转换成 4.4.2 基准表述再进行处理。即
模式识别
4.5 BFS 和 DFS
访问顺序与深度有关的问题,比如寻找最短路径,最长路径,按层访问记录的问题,用BFS;其他问题,用DFS。对于许多应用题,DFS相当于在backtracking节点的空间,只不过一个节点可能由多个节点访问到而已。
4.8 Graph Traversal
几乎所有的Graph问题都是在Graph Traversal的基础之上。与Tree Traversal的不同点在于,Graph 需要用 visited 这一collection 来避免重复访问(视具体问题,非严格必须);特定地,DFS需要用 visiting 或 indegrees这一collection 来探测 cycle(必须,避免死循环)。一个节点在 visiting 代表着这个节点或者这个节点出发的subgraph正在被访问,因此可以被去除;而在 visited 中仅代表这个节点曾经被访问过,因此一旦加入就不会被去除。
注意:如果需要检测cycle,BFS需要用topological sort的方法。(详见4.9)
另外,因为Graph可能存在多个root,因此可以循环从任意点出发访问,用 visited 避免重复地穷尽所有的节点。
如果需要按顺序记录访问的路径(e.g. topological sort),DFS可以把visited 改成OrderedDict 来正向记录当前section或当前路径访问过的节点,而BFS可以把 visited 改成 parent_map 或者 depth_map 这个hash table 来反向记录 parent 或 深度,前者最后通过backtracking 来结算这一路径。
【TODO】对于问题的潜在解之间存在重复部分的情况,DFS的return值必须体现subproblem的结果,应该将 visited 改成 hash 来实现考虑memoization,也就是 id 作为hash的key,return值也就是子问题的解,作为hash的value。这一点在Chapter 5中会详细描述。
e.g.1 There are
Nrooms and you start in room0. Each room may have some keys to access the next room. Returntrueif and only if you can enter every room. (LeetCode: Keys and Rooms)
e.g.2 There are a total of numCourses courses you have to take, labeled from 0 to numCourses-1.Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]. Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses? ( LeetCode: Course Schedule )
4.9 Topological Sort
e.g.1 There are a total of n courses you have to take labelled from 0 to n - 1. Some courses may have prerequisites, for example, if prerequisites[i] = [ai, bi] this means you must take the course bi before the course ai. Given the total number of courses numCourses and a list of the prerequisite pairs, return the ordering of courses you should take to finish all courses. ( LeetCode: Course Schedule II )
e.g.2 There is a new alien language which uses the latin alphabet. However, the order among letters are unknown to you. You receive a list of non-empty words from the dictionary, where words are sorted lexicographically by the rules of this new language. Derive the order of letters in this language. (LeetCode: Alien Dictionary)
Last updated
Was this helpful?