题意:
给定二叉树,按垂序遍历返回其结点值。
对位于 (X, Y) 的每个结点而言,其左右子结点分别位于 (X-1, Y-1) 和 (X+1, Y-1)。
把一条垂线从 X = -infinity 移动到 X = +infinity ,每当该垂线与结点接触时,我们按从上到下的顺序报告结点的值( Y 坐标递减)。
如果两个结点位置相同,则首先报告的结点值较小。
按 X 坐标顺序返回非空报告的列表。每个报告都有一个结点值列表。
实例:
提示:
- 树的结点数介于
1
和1000
之间。 - 每个结点值介于
0
和1000
之间。
解答:
1、遍历二叉树后,得到每个节点的位置和值(左节点x-1,y-1,右节点x+1, y-1, MyTreeNode(value, x, y)),保存在列表nodes中
2、对nodes进行排序,先安装x升序,再按照y升序,最后按照value升序(即,x:从左到右;y:从上到下:value-从小到大)
3、遍历nodes,同x值的放到同个list中,再将list放入结果列表ret中,最后返回。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { class MyTreeNode { int x; int y; int value; public MyTreeNode(int value, int x, int y) { this.x = x; this.y = y; this.value = value; } } public List<List<Integer>> verticalTraversal(TreeNode root) { if (root == null) { return Collections.EMPTY_LIST; } List<List<Integer>> ret = new ArrayList<List<Integer>>(); List<MyTreeNode> nodes = new ArrayList<>(); traverse(root, nodes, 0, 0); Collections.sort(nodes, new Comparator<MyTreeNode>() { @Override public int compare(MyTreeNode arg0, MyTreeNode arg1) { // TODO Auto-generated method stub if (arg0.x == arg1.x) { if (arg0.y == arg1.y) { return arg0.value - arg1.value; } else { return arg0.y - arg1.y; } } else { return arg0.x - arg1.x; } } }); int curX = nodes.get(0).x; List<Integer> sameXNodes = new ArrayList<>(); sameXNodes.add(nodes.get(0).value); for (int i = 1; i < nodes.size(); ++i) { int x = nodes.get(i).x; if (curX != x) { ret.add(new ArrayList<>(sameXNodes)); sameXNodes.clear(); } curX = x; sameXNodes.add(nodes.get(i).value); } ret.add(sameXNodes); return ret; } private void traverse(TreeNode root, List<MyTreeNode> nodes, int x, int y) { if (root == null) { return; } nodes.add(new MyTreeNode(root.val, x, y)); traverse(root.left, nodes, x - 1, y + 1); traverse(root.right, nodes, x + 1, y + 1); } }