给定二叉树,按垂序遍历返回其结点值。
对位于 (X, Y)
的每个结点而言,其左右子结点分别位于 (X-1, Y-1)
和 (X+1, Y-1)
。
把一条垂线从 X = -infinity
移动到 X = +infinity
,每当该垂线与结点接触时,我们按从上到下的顺序报告结点的值( Y
坐标递减)。
如果两个结点位置相同,则首先报告的结点值较小。
按 X
坐标顺序返回非空报告的列表。每个报告都有一个结点值列表。
示例 1:
输入:[3,9,20,null,null,15,7]
输出:[[9],[3,15],[20],[7]]
解释:
在不丧失其普遍性的情况下,我们可以假设根结点位于 (0, 0):
然后,值为 9 的结点出现在 (-1, -1);
值为 3 和 15 的两个结点分别出现在 (0, 0) 和 (0, -2);
值为 20 的结点出现在 (1, -1);
值为 7 的结点出现在 (2, -2)。
示例 2:
输入:[1,2,3,4,5,6,7]
输出:[[4],[2],[1,5,6],[3],[7]]
解释:
根据给定的方案,值为 5 和 6 的两个结点出现在同一位置。
然而,在报告 "[1,5,6]" 中,结点值 5 排在前面,因为 5 小于 6。
提示:
1
和 1000
之间。0
和 1000
之间解答:
用了一个Map里面嵌套Set,利用TreeMap的排序特性进行X的排序和分类;将y值和树的val值组合起来,然后用的TreeSet的排序特性给y值和val值进行排序,最后数据类型转换。这种方法的缺点就是不能应对,相同坐标具有相同值的特例,因为这种情况会将其中一个节点Set去重掉。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
TreeMap<Integer, Set> map = new TreeMap<>();
public List<List<Integer>> verticalTraversal(TreeNode root) {
dfs(root, 1000, 1000);
List<List<Integer>> lists = new ArrayList<>();
for (Set list : map.values()) {
List<Integer> newlist = new ArrayList<>();
for(Object i : list){
Integer a = (Integer) i;
newlist.add(a.intValue()%1000);
}
lists.add(newlist);
}
return lists;
}
void dfs(TreeNode root, int x ,int y) {
if (root == null) return;
else {
if (!map.containsKey(x)) {
Set<Integer> list = new TreeSet<>();
list.add(y*1000 + root.val);
map.put(x, list);
} else {
Set<Integer> list = map.get(x);
list.add(y*1000 + root.val);
}
}
dfs(root.left, x-1, y+1);
dfs(root.right, x+1, y+1);
}
}
UWI的方式,也差不多:
class Solution {
List<int[]> hi;
public List<List<Integer>> verticalTraversal(TreeNode root) {
hi = new ArrayList<>();
dfs(root, 0, 0);
Collections.sort(hi, new Comparator<int[]>() {
public int compare(int[] a, int[] b) {
if(a[1] != b[1])return a[1] - b[1];
if(a[2] != b[2])return -(a[2] - b[2]);
return a[0] - b[0];
}
});
List<List<Integer>> ret = new ArrayList<>();
for(int i = 0;i < hi.size();){
int j = i;
while(j < hi.size() && hi.get(j)[1] == hi.get(i)[1])j++;
List<Integer> item = new ArrayList<>();
for(int k = i;k < j;k++){
item.add(hi.get(k)[0]);
}
ret.add(item);
i = j;
}
return ret;
}
void dfs(TreeNode cur, int x, int y)
{
if(cur == null)return;
hi.add(new int[]{cur.val, x, y});
dfs(cur.left, x-1, y-1);
dfs(cur.right, x+1, y-1);
}
}