• [Leetcode] Populating next right pointer 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 toNULL.

    Initially, all next pointers are set toNULL.

    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

    题中要求二叉树为完美二叉树(满二叉树,Perfect binary tree),其性质为一个深度为k(>=-1)且有2^(k+1) - 1个结点。通俗的讲,叶节点处于同一层,除叶节点以外其他结点均有左右孩子。详情见博友veli的博客。题目要求用常数O(1)空间,故不能用队列等。
    要是能用队列,则可以用层次遍历中的方法三,然后每次从queue中取出一个元素时,将其next指针指向queue中下一个节点即可,可惜不满足题意。
    因为,不能用常规的队列解决问题,所以遇到几个难点。一、如何构成循环;二、如何从一个结点的左孩子转到右孩子。网友们给出了解题思路,非本人原创,这里仅给出自己的理解。
    思路:类似的层次遍历思想,用firLeft记录下每层的最左端的结点,然后从左往右遍历,值得注意的是,每层的最右端元素的next不必重新指向NULL ,因为,二叉树的结构体中,每个结点的next是自动赋为NULL的。这就产生一个问题:如何从一层转向下一层,即循环条件。因为,二叉树为完美二叉树,
    一般结点的(非叶节点)的左右孩子都是存在的,故可以以结点的左孩子或者右孩子是否存在来为条件;二是,如何在层内移动,核心思想为,用上一层的节点控制下一层的指向。对某一节点,其左孩子直接指向右孩子即可,节点之间,其next若是存在,则用该结点的右孩子指向其next的左孩子。最后
    firLeft=firLeft->left即可。
    /**
     * 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 *firLeft=root;
            while(firLeft->left)
            {
                TreeLinkNode *parNode=firLeft;
                while(parNode)
                {
                    parNode->left->next=parNode->right;
                    if(parNode->next)
                        parNode->right->next=parNode->next->left;
    
                    parNode=parNode->next;    
                }
                firLeft=firLeft->left;
            }    
        }
    };

    方法二:递归,见Grandyang的博客

    // 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 : NULL;
            connect(root->left);
            connect(root->right);
        }
    };
  • 相关阅读:
    git工具命令整理
    使用nodeJs操作redis
    electron 7.x 设置开发环境与生产模式 隐藏菜单栏和开发者工具 devtools
    electron 打包问题 解决
    sso单点登录之跨域cookie共享 (跨域缓存共享)
    浏览器线程执行顺序
    JS如何将变量作为一个对象的Key
    DevOps流程的简单总结
    通过key 寻找数组内对象的某一项
    根据key查找对象数组中符合的一项 返回对象(递归)
  • 原文地址:https://www.cnblogs.com/love-yh/p/6984527.html
Copyright © 2020-2023  润新知