[LeetCode]116. Populating Next Right Pointers in Each Node

树的层次遍历,递归,非递归

Posted by JinFei on February 18, 2020

题目描述

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.

Follow up:

You may only use constant extra space. Recursive approach is fine, you may assume implicit stack space does not count as extra space for this problem.

Example1:

Treeimage
Input: root = [1,2,3,4,5,6,7] Output: [1,#,2,3,#,4,5,6,7,#] 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. The serialized output is in level order as connected by the next pointers, with ‘#’ signifying the end of each level.

Constraints:

  1. The number of nodes in the given tree is less than 4096.
  2. -1000 <= node.val <= 1000

非递归解题思路

  • 这道题实际考察树的层次遍历
  • 非递归版本
    • 需要用到 queue 来辅助
    • 由于是层序遍历,每层的节点都按顺序加入 queue 中
    • 而每当从 queue 中取出一个元素时,将其 next 指针指向 queue 中下一个节点即可(层次遍历的时候,先取的是该层左边的节点,然后这个队列中首元素即为该左边节点的右边节点,将next指向 front 即可),
    • 对于每层的开头元素开始遍历之前,先统计一下该层的总个数,用个 for 循环,这样当 for 循环结束的时候,该层就已经被遍历完了
/*
// 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 == NULL){
            return root;
        }
        queue<Node*> q;
        q.push(root);
        while(!q.empty()){
            int size = q.size();
            
            for(int i = 0; i < size; i++){
                Node* node = q.front();
                q.pop();
                //if(q.size() >= 1){   // q.size是不断增加的
                if(i < size - 1){
                    node -> next = q.front();
                }
                if(node -> left){
                    q.push(node -> left);
                }
                if(node -> right){
                    q.push(node -> right);
                }
            }
        }
        return root;
    }
};

递归解题思路

  • 由于是完全二叉树,所以若节点的左子结点存在的话,其右子节点必定存在,所以左子结点的 next 指针可以直接指向其右子节点
  • 对于其右子节点的处理方法是,判断其父节点的 next 是否为空,若不为空,则指向其 next 指针指向的节点的左子结点,若为空则指向 NULL
/*
// 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 == NULL){
            return root;
        }
        if(root -> left){
            root -> left -> next = root -> right;
        }
        if(root -> right){
            root -> right -> next = root -> next != NULL ? root -> next -> left : NULL;
        }
        connect(root -> left);
        connect(root -> right);
        return root;
    }
    
};