【LeetCode & 剑指offer刷题】树题18:Populating Next Right Pointers in Each Node

【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

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.
  • Recursive approach is fine, implicit stack space does not count as extra space for this problem.
  • You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).
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

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) {}
 * };
 */
/*
方法一:递归法
Recursion, more than constant space
*/
class Solution
{
public:
    void connect(TreeLinkNode *root)
    {
        if (!root) return;
       
        //对根结点的左右子结点进行连接
        if (root->left)
            root->left->next = root->right; //连接左结点和右结点
        if (root->right)
            root->right->next = root->next? root->next->left : nullptr; //连接右结点与根结点右边结点的左结点
       
        //对左右子树递归连接
        connect(root->left);
        connect(root->right);
    }
};
/*掌握
方法二:迭代法
常数空间
*/
class Solution
{
public:
    void connect(TreeLinkNode *root)
    {
        if (!root) return;
       
        //start标记每一层的起始节点,cur用来遍历该层的节点
        TreeLinkNode *start = root, *cur = nullptr;
        while (start->left) //需要对下层处理,故要判断start->left
        {
            cur = start;
            while(cur) //每次连接下一层的next指针
            {
                //对根结点的左右子结点进行连接
                if (cur->left)
                    cur->left->next = cur->right; //连接左结点和右结点
                if (cur->right)
                    cur->right->next = cur->next? cur->next->left : nullptr; //连接右结点与根结点右边结点的左结点
               
                cur = cur->next;//该层的next指针已经由上一次的迭代处理好
            }
            start = start->left; //下一层的起始结点
        }
    }
};
 
 
 
 
//方法三:利用level-order中的递归遍历思想,功能实现了,但是用到了cache,空间复杂度为O(num of levels),不符合题目常数空间的要求(该方法不好!!)
class Solution
{
public:
    void connect(TreeLinkNode *root)
    {
        vector<TreeLinkNode*> cache; //用于存储每层上一节点的指针
        traverse(root, 1, cache);
    }
   
    void traverse(TreeLinkNode* root, int level, vector<TreeLinkNode*>& cache)
    {
       
        if(root == nullptr) return; //递归的出口
       
        if(cache.size() < level) cache.push_back(nullptr); //初始时存空指针
       
        root->next = cache[level-1];
        cache[level-1] = root;
        traverse(root->right, level+1, cache);//level-order按每层从右往左遍历
        traverse(root->left, level+1, cache);
    }
};
 
 

 

posted @ 2019-01-05 19:51  wikiwen  阅读(119)  评论(0编辑  收藏  举报