leetcode_117:填充每个节点的下一个右侧节点指针 II

这个题目和leetcode_116是类似的,但是这个题目不能其中的第二种解法,因为它并不是一个完全二叉树。但是第一种解法是可行的(原谅我第一种写法写的有点冗余,但是也不想改了,算是留着个教训吧)。

  1. 查看当前节点是父节点的左子节点还是右子节点。
  2. 如果是左子节点则查看右子节点是否为空:不为空则让左子节点的next指向右子节点;为空则顺着父节点的next指针向下找,直到找到一个有孩子节点的树,如果没找到这样的树则当前节点的next就为null,找到了则next指向其中的某个子节点(从左到右判断)。
  3. 如果是右子节点和第二种情况中右子节点为空的情况类似,即沿着父节点的next指针向下找。

这个地方有一个要注意的事项,就是当前节点改造完后,必须先对节点的右子树进行改造,然后才对节点的左子树进行改造。例如下面的例子,假如对根节点的左子树改造完后(即图中箭头1),然后继续向左,改造节点2的左子树(图中箭头2),然后继续向左改造节点4的左子树节点8,此时沿着父节点4的next指针只能到达节点5,最终导致节点8的next只能指向null。
在这里插入图片描述
如果先对右子树进行改造,那情况就不一样了。如图所示箭头上的数字代表next指针更改的顺序,因为先改造右子树,所以总能保证某个节点的父节点的next指针可以到达最右方。
在这里插入图片描述
完整代码如下:

    public Node connect(Node root) {
        if (root == null)
            return;
        helper(root, root.right);	//先改造右子树
        helper(root, root.left);	//后改造左子树
        return root;
    }

    private void helper(Node parent, Node root) {
        if (root == null)
            return;
        if (parent.left == root) {
            if(parent.right != null)	//若当前节点是个左子节点,且兄弟不为null,则其next直接指向兄弟
                root.next = parent.right;
            else {	//否则沿着父节点的next向下找
                Node p = parent.next;
                while (p != null && p.left == null && p.right == null)      //找到一个有子节点的根节点
                    p = p.next;
                if (p != null)  //p不为空则从左往右取最近的,p为空则直接使用默认的null即可
                    root.next = p.left != null ? p.left : p.right;
            }
        } else {	//是个右节点则直接沿着父节点的next指针向下找
            Node p = parent.next;
            while (p != null && p.left == null && p.right == null)      //找到一个有子节点的根
                p = p.next;
            if (p != null)  //p不为空则从左往右取最近的,p为空则直接使用默认的
                root.next = p.left != null ? p.left : p.right;
        }
        helper(root, root.right);	//先构造右子树
        helper(root, root.left);	//后构造左子树
    }
发布了96 篇原创文章 · 获赞 2 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/reachwang/article/details/103393370
今日推荐