[C++]LeetCode: 123 Populating Next Right Pointers in Each Node(链接完全二叉树)

本文介绍了一种将完美二叉树转化为每层节点相连的链表的方法,提供了两种解决方案:一种利用队列实现,另一种仅使用常数额外空间。通过这两种方法,可以有效地完成树节点间的链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

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

Answer 1: 使用队列

思路:我们维护一个前序节点和队列。队列用于把遍历到的节点压入队列,每次从队列中取出一个节点,如果前序节点非空,我们链接前序节点和当前节点,更新前序节点为当前节点。判断当前节点是否为NULL,如果是,则说明到达本层的最后,我们用NULL来区分每一层。注意只有在队列非空时,我们才加入层的区分标志NULL,否则在树的最后一层会造成死循环。

这种办法虽然AC 可是使用了队列来存储节点,空间复杂度是O(lg(N))。没有达到最优,下一种方法介绍一个O(1)的方法

Attention:

1. 如何连接前序节点和当前节点。

if(pre != NULL)
            {
                pre->next = node;
            }
            pre = node;
AC Code:
/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  TreeLinkNode *left, *right, *next;
 *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 * };
 */
class Solution {
public:
    void connect(TreeLinkNode *root) {
        queue<TreeLinkNode*> treeQ;
        if(root == NULL) return;
        treeQ.push(root);
        treeQ.push(NULL);
        TreeLinkNode* pre(NULL);
        
        while(!treeQ.empty())
        {
            TreeLinkNode* node = treeQ.front();
            treeQ.pop();
            
            if(pre != NULL)
            {
                pre->next = node;
            }
            pre = node;
            
            if(node != NULL)
            {
                if(node->left) treeQ.push(node->left);
                if(node->right) treeQ.push(node->right);
            }
            else
            {
                if(!treeQ.empty())
                {
                    treeQ.push(NULL);     //区分每层
                }
            }
        }
        return;
    }
};

Answer 2: 常数空间复杂度

思路:这道题是要求我们将一棵树的每一层维护成一个链表,树是给定的完全二叉树。这里我们其实不需要额外维护一个队列,因为这里每一层我们会维护成一个链表,可以从链表中得到下一个节点的信息。每一层链表的起点就是树每层最左的那个节点,也就是我们只需要维护一个链表的起始指针就可以依次得到整个队列了。我们维护两个节点指针,一个是每层队列的链表起始节点pre,一个是当前的根结点,用于连接它的孩子。如果当前节点不为空,说明还有孩子结点,还需要连接。我们根据题目要求连接孩子结点。一层结束后,我们更新pre为下一层的起始结点,即pre->left

复杂度:时间复杂度,对每个结点都要遍历一次,O(N), 空间不需要队列,O(1)

AC Code:

/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  TreeLinkNode *left, *right, *next;
 *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 * };
 */
class Solution {
public:
    void connect(TreeLinkNode *root) {
        if(root == NULL) return;
        TreeLinkNode* pre = root;  //pre维护着每一行的链表开始的根结点
        TreeLinkNode* cur = NULL;
        
        while(pre->left)
        {
            cur = pre;  //cur代表当前要链接的两个节点的根结点
            while(cur)
            {
                cur->left->next = cur->right;
                if(cur->next) cur->right->next = cur->next->left;  
                cur = cur->next; //cur跳到同行的下个根结点
            }
            pre = pre->left;
        }
    }
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值