图论的常见题目有两类,一类是求两点间最短距离,另一类是拓扑排序,两种写起来都很烦。
求最短路径:
127. Word Ladder
Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:
- Only one letter can be changed at a time
- Each intermediate word must exist in the word list
For example,
Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog"
,
return its length 5
.
Note:
- Return 0 if there is no such transformation sequence.
- All words have the same length.
All words contain only lowercase alphabetic characters.
从起点开始向外更新,因为每条路径的权值都不是负数,所以先更新的总比后更新的小。
已经被更新过的之后就不用考虑了
133. Clone Graph
Clone an undirected graph. Each node in the graph contains a label
and a list of its neighbors
.
OJ's undirected graph serialization:
Nodes are labeled uniquely.
We use#
as a separator for each node, and ,
as a separator for node label and each neighbor of the node.
As an example, consider the serialized graph {0,1,2#1,2#2,2}
.
The graph has a total of three nodes, and therefore contains three parts as separated by #
.
- First node is labeled as
0
. Connect node0
to both nodes1
and2
. - Second node is labeled as
1
. Connect node1
to node2
. - Third node is labeled as
2
. Connect node2
to node2
(itself), thus forming a self-cycle.
Visually, the graph looks like the following:
1 / / 0 --- 2 / \_/
Given n
nodes labeled from 0
to n - 1
and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.
For example:
Given n = 5
and edges = [[0, 1], [0, 2], [0, 3], [1, 4]]
, return true
.
Given n = 5
and edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]]
, return false
.
Hint:
- Given
n = 5
andedges = [[0, 1], [1, 2], [3, 4]]
, what should your return? Is this case a valid tree? - According to the definition of tree on Wikipedia: “a tree is an undirected graph in which any two vertices are connected by exactly one path. In other words, any connected graph without simple cycles is a tree.”
Note: you can assume that no duplicate edges will appear in edges
. Since all edges are undirected, [0, 1]
is the same as [1, 0]
and thus will not appear together in edges
.
public class Solution { public boolean validTree(int n, int[][] edges) { List<HashSet<Integer>> sets = new ArrayList<HashSet<Integer>>(); for (int i = 0; i < n; i++) { sets.add(new HashSet<Integer>()); } boolean[] isVisited = new boolean[n]; Arrays.fill(isVisited, false); for (int[] edge : edges) { int v1 = edge[0]; int v2 = edge[1]; sets.get(v1).add(v2); sets.get(v2).add(v1); } boolean result = dfs(sets, isVisited, 0, -1); if (!result) { return false; } for (int i = 0; i < n; i++) { if (!isVisited[i]) { return false; } } return true; } private boolean dfs(List<HashSet<Integer>> sets, boolean[] isVisited, int now, int prev) { boolean isV = isVisited[now]; if (isV) { return false; } isVisited[now] = true; for (Integer x : sets.get(now)) { if (x != prev && !dfs(sets, isVisited, x, now)) { return false; } } return true; } }
310. Minimum Height Trees
For a undirected graph with tree characteristics, we can choose any node as the root. The result graph is then a rooted tree. Among all possible rooted trees, those with minimum height are called minimum height trees (MHTs). Given such a graph, write a function to find all the MHTs and return a list of their root labels.
Format
The graph contains n
nodes which are labeled from 0
to n - 1
. You will be given the number n
and a list of undirected edges
(each edge is a pair of labels).
You can assume that no duplicate edges will appear in edges
. Since all edges are undirected, [0, 1]
is the same as [1, 0]
and thus will not appear together in edges
.
Example 1:
Given n = 4
, edges = [[1, 0], [1, 2], [1, 3]]
0 | 1 / 2 3
return [1]
Example 2:
Given n = 6
, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]
0 1 2 | / 3 | 4 | 5
return [3, 4]
Hint:
- How many MHTs can a graph have at most?
Note:
(1) According to the definition of tree on Wikipedia: “a tree is an undirected graph in which any two vertices are connected by exactly one path. In other words, any connected graph without simple cycles is a tree.”
(2) The height of a rooted tree is the number of edges on the longest downward path between the root and a leaf.
Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.
public class Solution { public List<Integer> findMinHeightTrees(int n, int[][] edges) { List<List<Integer>> graph = new ArrayList<List<Integer>>(n); if (n < 3 || edges.length == 0) { List<Integer> result = new ArrayList<Integer>(); if (n == 0) { return result; } else { for (int i = 0; i < n; i++) { result.add(i); } return result; } } for (int i = 0; i < n; i++) { List<Integer> list = new LinkedList<Integer>(); graph.add(list); } for (int[] edge : edges) { int v1 = edge[0]; int v2 = edge[1]; graph.get(v1).add(v2); graph.get(v2).add(v1); } int count = n; List<Integer> toRemove = new ArrayList<Integer>(); for (int i = 0; i < n; i++) { List<Integer> list = graph.get(i); if (list.size() == 1) { toRemove.add(i); } } while (!toRemove.isEmpty() && count > 1) { List<Integer> tmpRemove = new ArrayList<Integer>(); for (Integer leave : toRemove) { List<Integer> list0 = graph.get(leave); int parent = list0.get(0); list0.clear(); List<Integer> list = graph.get(parent); list.remove(leave); if (list.size() == 1) { tmpRemove.add(parent); } } count -= toRemove.size(); toRemove = tmpRemove; if (count <= 2) { break; } } List<Integer> result = new ArrayList<Integer>(); result.addAll(toRemove); return result; } }