987. Vertical Order Traversal of a Binary Tree

DFS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Solution {
public List<List<Integer>> verticalTraversal(TreeNode root) {
Map<Integer, Queue<int[]>> colIndexToNumListMap = new TreeMap<>(); // 值选择优先队列而不是 TreeSet 是因为可能存在重复元素
dfs(colIndexToNumListMap, root, 0, 0);
List<List<Integer>> resultList = new ArrayList<>();
for (Queue<int[]> numQueue : colIndexToNumListMap.values()) {
List<Integer> numList = new ArrayList<>(numQueue.size());
while (!numQueue.isEmpty()) { // 注意优先队列整体无序,使用 for 循环遍历并非有序,所以此处依次弹出最小值节点
numList.add(numQueue.poll()[2]);
}
resultList.add(numList);
}
return resultList;
}

private void dfs(Map<Integer, Queue<int[]>> colIndexToNumListMap, TreeNode node, int i, int j) {
if (node == null) {
return;
}

Queue<int[]> queue = colIndexToNumListMap.computeIfAbsent(j, k -> new PriorityQueue<>((o1, o2) -> {
int diff = Integer.compare(o1[0], o2[0]);
if (diff != 0) {
return diff;
} else {
return Integer.compare(o1[2], o2[2]);
}
}));
queue.offer(new int[]{i, j, node.val});

dfs(colIndexToNumListMap, node.left, i + 1, j - 1);
dfs(colIndexToNumListMap, node.right, i + 1, j + 1);
}
}

以上解法通过在 DFS 遍历过程中构建结果集。

DFS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
class Solution {
private static class TreeNodeWrapper {
private final int val;
private final int row;
private final int col;

public TreeNodeWrapper(int val, int row, int col) {
this.val = val;
this.row = row;
this.col = col;
}
}

public List<List<Integer>> verticalTraversal(TreeNode root) {
List<List<Integer>> resultList = new ArrayList<>();

List<TreeNodeWrapper> treeNodeWrapperList = new ArrayList<>();
dfs(treeNodeWrapperList, root, 0, 0);

Collections.sort(treeNodeWrapperList, (o1, o2) -> {
if (o1.col != o2.col) {
return Integer.compare(o1.col, o2.col);
} else {
if (o1.row != o2.row) {
return Integer.compare(o1.row, o2.row);
} else {
return Integer.compare(o1.val, o2.val);
}
}
});

for (int i = 0; i < treeNodeWrapperList.size(); i++) {
TreeNodeWrapper curr = treeNodeWrapperList.get(i);
if (i == 0) {
List<Integer> list = new ArrayList<>();
list.add(curr.val);
resultList.add(list);
} else {
TreeNodeWrapper prev = treeNodeWrapperList.get(i - 1);
if (curr.col == prev.col) {
resultList.get(resultList.size() - 1).add(curr.val);
} else {
List<Integer> list = new ArrayList<>();
list.add(curr.val);
resultList.add(list);
}
}
}

return resultList;
}

private void dfs(List<TreeNodeWrapper> treeNodeWrapperList, TreeNode node, int row, int col) {
if (node == null) {
return;
}

treeNodeWrapperList.add(new TreeNodeWrapper(node.val, row, col));
dfs(treeNodeWrapperList, node.left, row + 1, col - 1);
dfs(treeNodeWrapperList, node.right, row + 1, col + 1);
}
}

以上解法通过 DFS 收集所有节点至一个平级列表,再排序拆分为题目要求的二级列表。

References

987. Vertical Order Traversal of a Binary Tree
PriorityQueue (Java Platform SE 8)
Sorting Priority Queue in Java
The built-in iterator for java’s PriorityQueue does not traverse the data structure in any particular order. Why?