leetcode 之Populating Next Right Pointers in Each Node解题思路

题目如下:

Given a binary tree

    struct TreeLinkNode {
      TreeLinkNode *left;
      TreeLinkNode *right;
      TreeLinkNode *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.

Note:

  • You may only use constant extra space.
  • You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).

For example,
Given the following perfect binary tree,

         1
       /  \
      2    3
     / \  / \
    4  5  6  7

After calling your function, the tree should look like:

         1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \  / \
    4->5->6->7 -> NULL

题目的大体意思就是将一颗满二叉树转变成三叉树,每一个节点的next值指向它右边的节点,如果右边没有节点的话,置为Null,初始值都为null。


下面给出解题思路:

从图上的例子就可以看出,添加next属性是按层次添加的,所以该题有点类似于层次遍历。因此可以采用一个辅助数据结构--队列。


节点4的next节点就指向其后面的节点。节点5,6依次如此。

和层次遍历不同的是,这里需要记录每个节点所属的层次,否则如果7后面添加了下一层次的节点,按照上面的算法节点7的next节点将会指向其后面的节点,就是错误的。

那如何记录每一个节点的层次呢?

其实也不用额外开辟空间记录每个节点的层次,这里我们只需要记录每一层有多少节点,那我们就会更改(节点个数 - 1)个next指针。如上图,该层次有4个节点,只要更改3个next指针即可,所以用一层while循环控制就ok了。每次获取一对节点,因此第一个节点用删除头结点的方式,第二个节点用获取头节点但是不删除的方式。直到剩下最后一对节点,用同时删除两个头结点的方式。

每一层的节点数是2的次幂,比较容易计算。

/**
 * Definition for binary tree with next pointer.
 * public class TreeLinkNode {
 *     int val;
 *     TreeLinkNode left, right, next;
 *     TreeLinkNode(int x) { val = x; }
 * }
 */
public class Solution {
    public void connect(TreeLinkNode root) {
        if(root == null || (root.left == null && root.right == null)) return;
        Queue<TreeLinkNode> queue = new LinkedList<TreeLinkNode>();
        int level = 1;
        queue.add(root.left);
        queue.add(root.right);
        while(queue.peek() != null){//如果队列不为空,即进行循环
            int times = (int)Math.pow(2,level) - 1;//记录每一层的节点个数
            TreeLinkNode first = null;
            TreeLinkNode second = null;
            while(times > 1){
                first = queue.remove();//先删除头结点
                second = queue.element();//获取头结点但不删除
                first.next = second;
                queue.add(first.left);
                queue.add(first.right);
                times--;
            }
            //剩下最后一对节点,同时删除头结点
            first = queue.remove();
            second = queue.remove();
            first.next = second;
            queue.add(first.left);
            queue.add(first.right);
            queue.add(second.left);
            queue.add(second.right);
            level++;//当一层结束之后,层次增加
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值