zoukankan      html  css  js  c++  java
  • leetCode987 二叉树的垂序遍历(hard)

    好久没更新了,因为刚换了工作,比较忙。这次更新就由这道表面hard,实则medium的题目开始吧,同时希望自己的生活工作哪怕遇到hard,但也能积极面对,最后发现其实也就那回事!

    审题:

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

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

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

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

    来源:力扣(LeetCode)
    读完题目,应该还是很明白的,就是从左到右,从上到下,相同位置则从小到大,来对二叉树进行遍历

    思考:

    我们可以记录每个节点的位置信息,比如可以定义一个int[] a, a[0]记录x轴坐标,a[1]记录y轴坐标,a[2]记录节点的值,然后用一个list去储存这个a,最后对list按照上面的要求来进行排序即可,详细见代码和注释:

            public List<List<Integer>> verticalTraversal(TreeNode root) {
                List<int[]> list = new ArrayList<>();
                listNode(root, list, null, true);
                // 从左到右,从上到下,相同位置则从小到大进行排序
                list.sort((o1, o2) -> {
                    if (o1[0] != o2[0]) {
                        return o1[0] - o2[0];
                    } else if (o1[1] != o2[1]) {
                        return o1[1] - o2[1];
                    } else return o1[2] - o2[2];
                });
    
                List<List<Integer>> re = new ArrayList<>();
                List<Integer> ll = new ArrayList<>();
                // 进行分组,同一个x坐标则在一个组
                for (int i = 0; i < list.size() - 1; i++) {
                    ll.add(list.get(i)[2]);
                    if (list.get(i)[0] != list.get(i + 1)[0]) {
                        re.add(ll);
                        ll = new ArrayList<>();
                    }
                }
                // 处理一下最右边的一个节点
                ll.add(list.get(list.size() - 1)[2]);
                re.add(ll);
                return re;
            }
    
    
            /**
             * 进行递归先序遍历,为了通过父节点信息对子节点位置进行计算
             * 定义一个int[3] 分别存x y val
             *
             * @param fa 父亲节点的位置信息
             * @param b  左节点true 右节点false
             */
            void listNode(TreeNode node, List<int[]> list, int[] fa, boolean b) {
                if (node == null) return;
                int[] a = new int[3];
                // fa为null 的时候说明是父亲节点,那么x=0,y=0,默认值
                if (fa != null) {
                    if (b) {
                        // 左节点x向左进行偏移一位
                        a[0] = fa[0] - 1;
                    } else {
                        // 右节点x向右进行偏移一位
                        a[0] = fa[0] + 1;
                    }
                    // 无论左右节点,y都要+1
                    a[1] = fa[1] + 1;
                }
                //保存节点值
                a[2] = node.val;
                list.add(a);
                listNode(node.left, list, a, true);
                listNode(node.right, list, a, false);
            }

    总结:

    这道题思路还是很清晰的,一定要熟练掌握二叉树的遍历,尤其是进行遍历的时候,保存一些状态值。

  • 相关阅读:
    也用一下Windows Live Writer
    常用16种iOS视图切换动画
    iPad平板电脑程序开发基础规则(源址:http://www.cocoachina.com/bbs/simple/?t82559.html)
    NSXMLParser详解
    UIScrollView用法
    使用UIActivityIndicatorView 和多线程
    为视图加边框
    iPhone SDK开发基础之iPhone程序框架
    NSXMLParser详解(事例)
    iOS开发 小知识点
  • 原文地址:https://www.cnblogs.com/junlancer/p/15085818.html
Copyright © 2011-2022 走看看