LeetCode-Day83(C++) 116. 填充每个节点的下一个右侧节点指针

  1. 填充每个节点的下一个右侧节点指针
    给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

初始状态下,所有 next 指针都被设置为 NULL。

进阶:

你只能使用常量级额外空间。
使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。

示例:
在这里插入图片描述

输入:root = [1,2,3,4,5,6,7]
输出:[1,#,2,3,#,4,5,6,7,#]
解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化的输出按层序遍历排列,同一层节点由 next 指针连接,’#’ 标志着每一层的结束。

提示:

树中节点的数量少于 4096
-1000 <= node.val <= 1000

方法二:使用已建立的 next 指针
思路

一棵树中,存在两种类型的next 指针。

第一种情况是连接同一个父节点的两个子节点。它们可以通过同一个节点直接访问到,因此执行下面操作即可完成连接。

node.left.next = node.right

在这里插入图片描述

第二种情况在不同父亲的子节点之间建立连接,这种情况不能直接连接。
在这里插入图片描述

如果每个节点有指向父节点的指针,可以通过该指针找到 next 节点。如果不存在该指针,则按照下面思路建立连接:

第 N 层节点之间建立 next 指针后,再建立第N+1 层节点的next 指针。可以通过 next 指针访问同一层的所有节点,因此可以使用第N 层的 next 指针,为第 N+1 层节点建立 next 指针。

算法

从根节点开始,由于第 0 层只有一个节点,所以不需要连接,直接为第 1 层节点建立 next 指针即可。该算法中需要注意的一点是,当我们为第 N 层节点建立next 指针时,处于第N−1 层。当第 N 层节点的 next 指针全部建立完成后,移至第 N 层,建立第 N+1 层节点的 next 指针。

遍历某一层的节点时,这层节点的 next 指针已经建立。因此我们只需要知道这一层的最左节点,就可以按照链表方式遍历,不需要使用队列。

上面思路的伪代码如下:

leftmost = root
while (leftmost.left != null) {
    head = leftmost
    while (head.next != null) {
        1) Establish Connection 1
        2) Establish Connection 2 using next pointers
        head = head.next
    }
    leftmost = leftmost.left
}

两种类型的next 指针。

第一种情况两个子节点属于同一个父节点,因此直接通过父节点建立两个子节点的 next 指针即可。

node.left.next = node.right

在这里插入图片描述

第二种情况是连接不同父节点之间子节点的情况。更具体地说,连接的是第一个父节点的右孩子和第二父节点的左孩子。由于已经在父节点这一层建立了 next 指针,因此可以直接通过第一个父节点的 next 指针找到第二个父节点,然后在它们的孩子之间建立连接。

node.right.next = node.next.left

在这里插入图片描述

完成当前层的连接后,进入下一层重复操作,直到所有的节点全部连接。进入下一层后需要更新最左节点,然后从新的最左节点开始遍历该层所有节点。因为是完美二叉树,因此最左节点一定是当前层最左节点的左孩子。如果当前最左节点的左孩子不存在,说明已经到达该树的最后一层,完成了所有节点的连接。
在这里插入图片描述

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/solution/tian-chong-mei-ge-jie-dian-de-xia-yi-ge-you-ce-2-4/

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;
    Node* next;

    Node() : val(0), left(NULL), right(NULL), next(NULL) {}

    Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}

    Node(int _val, Node* _left, Node* _right, Node* _next)
        : val(_val), left(_left), right(_right), next(_next) {}
};
*/

class Solution {
public:
    Node* connect(Node* root) {
        if (root == nullptr) return nullptr;

        Node* leftmost = root;

        while (leftmost->left != nullptr) {
            Node* head = leftmost;

            while (head != nullptr) {
                head->left->next = head->right;
            
                if (head->next != nullptr)
                    head->right->next = head->next->left;

                head = head->next;
            }

            leftmost = leftmost->left;
        }

        return root;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值