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
class Solution {
public List<List<Integer>> verticalOrder(TreeNode root) {
if (root == null) {
return new ArrayList<>();
}
Map<Integer, List<Integer>> colNodesMap = new HashMap<>();
Queue<Pair<TreeNode, Integer>> q = new LinkedList<>();
q.offer(new Pair<>(root, 0));
int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
while (!q.isEmpty()) {
Pair<TreeNode, Integer> currPair = q.poll();
colNodesMap.putIfAbsent(currPair.getValue(), new ArrayList<>());
colNodesMap.get(currPair.getValue()).add(currPair.getKey().val);
if (currPair.getKey().left != null) {
q.offer(new Pair<>(currPair.getKey().left, currPair.getValue() - 1));
}
if (currPair.getKey().right != null) {
q.offer(new Pair<>(currPair.getKey().right, currPair.getValue() + 1));
}
min = Math.min(min, currPair.getValue());
max = Math.max(max, currPair.getValue());
}
List<List<Integer>> ans = new ArrayList<>();
for (int i = min; i <= max; i++) {
ans.add(new ArrayList<>(colNodesMap.get(i)));
}
return ans;
}
}

BFS, 然后我们用map记录遇到的col中node得的值, 因此key-value pair是Integer : List, integer代表col的index, List代表这个col里的nodes的值. 需要注意的是, 我们需要知道col的min和max, 于是我们维护两个变量来知道最左到达哪里(min), 最右到达哪里(max), 然后遍历按照顺序遍历map即可. 这也就是最后一步39, 40行干的事情.

其实一开始我就在想, col以及该col有的nodes知道后, 怎么按照col的index从小到大遍历呢? 本来以为用tree map, 但是感觉有点儿得不偿失, 后来看解析发现要么就是把map中的key set取出来放到list, 然后sort, 最后按照这个sort好的key list去从左到右访问map, 这样就是从小到大. 后来的第二种解法就是我们上面的这个, 只需要知道col的range即可, 把range里面的list从小到大取出来即可, 因为col的index肯定是连续的, tree中没有断枝.

时间复杂度: O(n) n是nodes的个数.
空间复杂度: O(n) n是nodes的个数, 因为可能是perfect tree.