二叉树的垂直遍历

Posted by 令德湖周杰伦 on 04-12,2024

题目

给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列。

对位于 (row, col) 的每个结点而言,其左右子结点分别位于 (row + 1, col - 1) 和 (row + 1, col + 1) 。树的根结点位于 (0, 0) 。

二叉树的 垂序遍历 从最左边的列开始直到最右边的列结束,按列索引每一列上的所有结点,形成一个按出现位置从上到下排序的有序列表。如果同行同列上有多个结点,则按结点的值从小到大进行排序。

返回二叉树的 垂序遍历 序列。

思路

  1. 二叉树dp的方式收集树上的信息,info(col,row,val)
  2. 通过col,row,val的从小到大排序树上的节点信息
  3. 整合信息:如果col一样的放在一个list中, 并返回结果

解法


    public List<List<Integer>> verticalTraversal(TreeNode root) {
        if(root == null){
            return null;
        }
        //1.收集整棵的信息,存在resultList
        List<Info> resultList = new ArrayList<>();
        process(root, true, null, resultList);
        //2.通过col,row,val的从小到大排序,树上的节点信息
        Collections.sort(resultList, new Comparator<Info>() {
            @Override
            public int compare(Info o1, Info o2) {
                if(o1.col != o2.col){
                    return o1.col - o2.col;
                }else if(o1.row != o2.row){
                    return o1.row - o2.row;
                }else {
                    return o1.val - o2.val;
                }
            }
        });
        //3.整合信息:如果col一样的放在一个list中
        List<List<Integer>> ans = new ArrayList<>();
        int lastCol = Integer.MAX_VALUE;
        int i = 0;
        for (Info info : resultList) {
            if (info.col != lastCol) {
                lastCol = info.col;
                ans.add(new ArrayList<>());
                i++;
            }
            ans.get(i - 1).add(info.val);
        }

        return ans;
    }


    public void process(TreeNode node, boolean left, Info rootInfo, List<Info> resultList){
        if(node == null){
            return;
        }
        Info nodeInfo;
        //收集自己的信息
        if(rootInfo == null ){
            nodeInfo = new Info(0,0, node.val);
        }else {
            if(left){
                nodeInfo = new Info(rootInfo.row + 1, rootInfo.col - 1, node.val);
            }else{
                nodeInfo = new Info(rootInfo.row + 1, rootInfo.col + 1, node.val);
            }
        }
        resultList.add(nodeInfo);
        //收集子树的信息
        process(node.left, true, nodeInfo, resultList);
        process(node.right, false, nodeInfo, resultList);
    }


    static class Info{
        private int val;
        private int col;
        private int row;

        public Info(int row, int col ,int val){
            this.col = col;
            this.row = row;
            this.val = val;
        }
    }