核心思路:
自定义排序
每个节点有三个属性:值val,行坐标row,列坐标col
1、先按列排序,从小到大;
2、列相同,再按行排序,从小到大;
3、行相同,按值的大小排序,从小到大。
所以我们有两种实现思路:用双哈希表或者结构体自定义排序
双哈希表:
一个表存储列,一个表存储行,用数组每次记录数据,然后对数组进行自定义排序
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
Map<Integer,Integer> colmap=new HashMap<>();
Map<Integer,Integer> rowmap=new HashMap<>();
List<Integer> path=new ArrayList<>();
public List<List<Integer>> verticalTraversal(TreeNode root) {
dfs(root,0,0);
List<List<Integer>> ans=new ArrayList<>();
Collections.sort(path,new Comparator<Integer>(){
@Override
public int compare(Integer a,Integer b){
if(colmap.get(a)==colmap.get(b)){
if(rowmap.get(a)==rowmap.get(b))return a-b;
return rowmap.get(a)-rowmap.get(b);
}
return colmap.get(a)-colmap.get(b);
}
});
List<Integer> res=new ArrayList<>();
res.add(path.get(0));
for(int i=1;i<path.size();i++){
int ch=path.get(i);
int chl=path.get(i-1);
if(colmap.get(ch)!=colmap.get(chl)){
ans.add(res);
res=new ArrayList<>();
}
res.add(ch);
}
ans.add(res);
return ans;
}
public void dfs(TreeNode root,int row,int col){
if(root==null)return;
path.add(root.val);
rowmap.put(root.val,row);
colmap.put(root.val,col);
dfs(root.left,row+1,col-1);
dfs(root.right,row+1,col+1);
}
}
或者用treemap
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
Map<Integer,List<Integer>> map=new TreeMap<>();
Map<Integer,Integer> ceq=new HashMap<>();
public List<List<Integer>> verticalTraversal(TreeNode root) {
dfs(root,0,0);
List<List<Integer>> ans=new ArrayList<>();
for(int ch:map.keySet()){
List<Integer> path=map.get(ch);
Collections.sort(path,new Comparator<Integer>(){
@Override
public int compare(Integer a,Integer b){
if(ceq.get(a)==ceq.get(b))return a-b;
return ceq.get(a)-ceq.get(b);
}
});
ans.add(path);
}
return ans;
}
public void dfs(TreeNode root,int row,int col){
if(root==null)return;
List<Integer> path=map.getOrDefault(col,new ArrayList<>());
path.add(root.val);
ceq.put(root.val,row);
map.put(col,path);
dfs(root.left,row+1,col-1);
dfs(root.right,row+1,col+1);
}
}
结构体:
思想跟上述一样:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
class Node{
int val;
int col;
int row;
Node(int x){
this.val=x;
}
}
List<Node> path=new ArrayList<>();
public List<List<Integer>> verticalTraversal(TreeNode root) {
dfs(root,0,0);
List<List<Integer>> ans=new ArrayList<>();
Collections.sort(path,new Comparator<Node>(){
@Override
public int compare(Node a,Node b){
if(a.col==b.col){
if(a.row==b.row)return a.val-b.val;
return a.row-b.row;
}
return a.col-b.col;
}
});
List<Integer> res=new ArrayList<>();
res.add(path.get(0).val);
for(int i=1;i<path.size();i++){
Node ch=path.get(i);
Node chl=path.get(i-1);
if(ch.col!=chl.col){
ans.add(res);
res=new ArrayList<>();
}
res.add(ch.val);
}
ans.add(res);
return ans;
}
public void dfs(TreeNode root,int row,int col){
if(root==null)return;
Node ch=new Node(root.val);
ch.row=row;
ch.col=col;
path.add(ch);
dfs(root.left,row+1,col-1);
dfs(root.right,row+1,col+1);
}
}