力扣 - 987. 二叉树的垂序遍历
题目
思路
- 垂直遍历就是在同一行中,由上到小输出,然后再由小的列到大的列进行输出
- 可以将节点用二维坐标表示,
- 先将节点绑定坐标信心存入到locations集合中,按照我们自定义的方式进行排序
- 排序完后,在遍历该集合,如果x相同,那么就加入到同一个子集合中,如果x不相同,那么就将x添加到新的子集合中
代码
class Solution {
// localtions用来暂时存储坐标信息和值
LinkedList<Location> locations;
public List<List<Integer>> verticalTraversal(TreeNode root) {
// 初始化locations
locations = new LinkedList<>();
// dfs遍历所有节点
dfs(root, 0, 0);
// 将存储再集合中的所有结点按照我们自定义进行排序
Collections.sort(locations);
// 结果集
List<List<Integer>> res = new LinkedList<>();
// pre用于记录前一个的节点信息,因为如果x相同,那么就add入同一个集合中
Location pre = locations.get(0);
// 初始化第一个子集合
res.add(new LinkedList<>());
// 遍历排序好的节点
for (Location l : locations) {
// 如果x不相等,那么就是新的一列了,我们需要初始化一个新的子集合来存储元素
if (l.x != pre.x) {
res.add(new LinkedList<>());
// 更新pre的值
pre = l;
}
// 无论如何,都要将节点的值add入集合中,如果if没有执行,那么就add到上一个的集合中,如果if执行了,那么就add到新的子集合中
res.get(res.size() - 1).add(l.val);
}
// 得出结果
return res;
}
// dfs深度优先搜索(前序遍历)
private void dfs(TreeNode node, int x, int y) {
if (node != null) {
// 将节点值及其坐标信息添加到该集合中
locations.add(new Location(x, y, node.val));
//递归
dfs(node.left, x-1, y+1);
dfs(node.right, x+1, y+1);
}
}
}
/**
* 创建类用来存储二维空间地址和值
*/
class Location implements Comparable<Location> {
// 坐标
public int x;
public int y;
// 值
public int val;
public Location(int x, int y, int val) {
this.x = x;
this.y = y;
this.val = val;
}
// 重写比较的方法
@Override
public int compareTo(Location that) {
if (this.x != that.x) {
return Integer.compare(this.x, that.x);
} else if (this.y != that.y) {
return Integer.compare(this.y, that.y);
} else {
return Integer.compare(this.val, that.val);
}
}
}
复杂度分析
- 时间复杂度:\(O(NlogN)\),其中 N 为树的节点数
- 空间复杂度:\(O(N)\),其中 N 为树的节点数
我走得很慢,但我从不后退!

浙公网安备 33010602011771号