LeetCode 117. Populating Next Right Pointers in Each Node II

98 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第27天,点击查看活动详情

LeetCode 117. Populating Next Right Pointers in Each Node II

给定一个二叉树

struct Node {
  int val;
  Node *left;
  Node *right;
  Node *next;
}

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL

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

 

进阶:

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

 

示例:

输入:root = [1,2,3,4,5,null,7]
输出: [1,#,2,3,#,4,5,7,#]
解释: 给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化输出按层序遍历顺序(由 next 指针连接),'#' 表示每层的末尾。

 

提示:

  • 树中的节点数小于 6000
  • -100 <= node.val <= 100

算法

(BFS,树的遍历) O(n) 这道题目和 Populating Next Right Pointers in Each Node 类似,不同点在于这道题目的输入数据不一定是一棵完美二叉树。

从根节点开始宽度优先遍历,每次遍历一层,从左到右依次遍历每个节点。 遍历时维护下一层节点的链表。对于每个节点,依次判断它的左儿子和右儿子是否在存在,如果存在,则插入下一层链表的末尾。

为了便于理解,我们模拟一下样例的操作流程:

第一步,遍历根节点,依次将它的左右儿子插入下一层链表,得到 2->3; 第二步,从左到右遍历第二层,即遍历 2->3,依次将它们的子节点插入下一层链表,得到 4->5->7; 第三步,遍历到叶节点层,算法结束; 时间复杂度分析:每个节点仅会遍历一次。对于每个节点,遍历时维护下一层链表的时间复杂度是 O(1),所以总时间复杂度是 O(n)。

C++ 代码

/**
 * 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:
    Node* connect(Node *root) {
        auto head = root;
        while (root)
        {
            Node *dummy = new Node(0);
            Node *tail = dummy;
            while (root)
            {
                if (root->left)
                {
                    tail->next = root->left;
                    tail = tail->next;
                }
                if (root->right)
                {
                    tail->next = root->right;
                    tail = tail->next;
                }
                root = root->next;
            }
            root = dummy->next;
        }
        return head;
    }
};