LeetCode Top Interview Questions 116. Populating Next Right Pointers in Each Node (Java版; Medium)

welcome to my blog

LeetCode Top Interview Questions 116. Populating Next Right Pointers in Each Node (Java版; Medium)

题目描述
You are given a perfect binary tree where all leaves are on the same level, and every parent has two children. The binary tree has the following definition:

struct Node {
  int val;
  Node *left;
  Node *right;
  Node *next;
}
Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL.

Initially, all next pointers are set to NULL.

Example:

Input: {"$id":"1","left":{"$id":"2","left":{"$id":"3","left":null,"next":null,"right":null,"val":4},"next":null,"right":{"$id":"4","left":null,
"next":null,"right":null,"val":5},"val":2},"next":null,"right":{"$id":"5","left":{"$id":"6","left":null,"next":null,"right":null,"val":6},
"next":null,"right":{"$id":"7","left":null,"next":null,"right":null,"val":7},"val":3},"val":1}

Output: {"$id":"1","left":{"$id":"2","left":{"$id":"3","left":null,"next":{"$id":"4","left":null,"next":{"$id":"5","left":null,"next":{"$id":"6",
"left":null,"next":null,"right":null,"val":7},"right":null,"val":6},"right":null,"val":5},"right":null,"val":4},"next":{"$id":"7","left":{"$ref":"5"},
"next":null,"right":{"$ref":"6"},"val":3},"right":{"$ref":"4"},"val":2},"next":null,"right":{"$ref":"7"},"val":1}

Explanation: Given the above perfect binary tree (Figure A), your function should populate each next pointer to point to its next right node, 
just like in Figure B.


Note:

You may only use constant extra space.
Recursive approach is fine, implicit stack space does not count as extra space for this problem.
画图对分析非常有帮助; 有些情况一看就懂了

第一次做; 这道题最大的难点: 如何处理非兄弟节点; 循环版, 一层一层的处理; 下面的递归解法是DFS的顺序处理
class Solution {
    public Node connect(Node root) {
        if(root==null || root.left==null)
            return root;
        Node level_start = root;
        Node cur;
        //如果当前层不是null
        while(level_start!=null){
            //处理当前层所有节点的孩子节点
            cur = level_start;
            while(cur!=null){
                //兄弟节点之间的连接
                if(cur.left!=null)
                    cur.left.next = cur.right;
                //非兄弟节点之间的连接
                if(cur.next!=null && cur.right!=null)
                    cur.right.next = cur.next.left;
                //update
                cur = cur.next;
            }
            //update; 指向下一层的头结点
            level_start = level_start.left;
        }
        return root;
    }
}
第一次做; 这道题最大的难点: 如何处理非兄弟节点; base case的返回值要留意, 不能无脑返回null, 这道题应该返回root; 本题的灵魂是使用root.next信息, 打通了非兄弟节点之间的连接; 实际上使用了DFS思想, 具体用前序遍历实现! 二叉树的遍历是根基
class Solution {
    /*
    直觉上是对各个节点执行相同的操作, 所以用递归, 不过递归函数的当前节点没有其兄弟节点的信息(开始时这里分析错了, 需要利用兄弟节点信息, 而且相当重要!), 所以在递归函数中处理当前节点的左右孩子节点
    */
    public Node connect(Node root) {
        //base case; 
        /*
        因为是完美二叉树, 如果没有左孩子,也就没有右孩子, 既然没有孩子节点, 也就不用处理了
        为什么不用处理叶子节点? 因为处理叶子节点的父节点时已经处理了叶子节点, 所以要明确递归函数逻辑, 本题的递归函数处理的是当前节点的孩子节点;
        */
        if(root==null)
            return null;
        if(root.left==null)
            return root;
        //
        
        root.left.next = root.right;
        //这一步打通了非兄弟节点的连接
        if(root.next!=null){
            root.right.next = root.next.left;
        }
        
        //新条件新递归
        connect(root.left);
        connect(root.right);
        //感觉这个返回值没什么用, 确实没什么用
        return root;
    }
}
LeetCode题解, 循环版; 核心:一层一层横向处理
public class Solution {
    public void connect(TreeLinkNode root) {
        TreeLinkNode level_start=root;
        while(level_start!=null){
            TreeLinkNode cur=level_start;
            while(cur!=null){
                if(cur.left!=null) cur.left.next=cur.right;
                if(cur.right!=null && cur.next!=null) cur.right.next=cur.next.left;
                
                cur=cur.next;
            }
            level_start=level_start.left;
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值