LeetCode 之 Populating Next Right Pointers in Each Node I II — C++ 实现

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.
  • 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
给定一个二叉树,

 struct TreeLinkNode {
      TreeLinkNode *left;
      TreeLinkNode *right;
      TreeLinkNode *next;
    }

将每个节点的 next  指针指向其右边相邻的节点。如果没有下一个节点,则 next 设成 NULL

初始状态下所有的 next 指针为 NULL

说明:

空间复杂度为 O(1)。

树为满二叉树。

例如,给定下面的满二叉树,

         1
       /  \
      2    3
     / \  / \
    4  5  6  7

调用函数后,树如下列形式。

         1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \  / \
    4->5->6->7 -> NULL


分析:

    广度搜索。从顶层开始每次利用上一层已经连接好的链表从左往右扫描,然后找到其左右孩子(即连接好层的下一层)并将其连接。比如,第 i 层已经连接好,则从第 i 层的最左端节点开始逐个扫描,同时找到其左右孩子(第 i+1 层)连接,注意第 i 层当前节点的右孩子和其兄弟节点的左孩子也要连接。

class Solution {
public:
    void connect(TreeLinkNode *root) {
        if(!root) //空
        {
            return;
        }
        
        TreeLinkNode *pLevel = root, *pStart = NULL;
        while(pLevel->left)//广度遍历,利用上一层已经连接好的next来链接下一层
        {
            pStart = pLevel; //指向当前层开始位置
            while(pStart)
            {
                pStart->left->next = pStart->right;//连接下一层
                if(pStart->next) //当前层还有兄弟节点
                {
                    pStart->right->next = pStart->next->left;
                }
                
                pStart = pStart->next;
            }
            
            pLevel = pLevel->left; //指向下一层
        }
        
        return;
    }
};

Populating Next Right Pointers in Each Node II

 

Follow up for problem "Populating Next Right Pointers in Each Node".

What if the given tree could be any binary tree? Would your previous solution still work?

Note:

  • You may only use constant extra space.

For example,
Given the following binary tree,

         1
       /  \
      2    3
     / \    \
    4   5    7

After calling your function, the tree should look like:

         1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \    \
    4-> 5 -> 7 -> NULL
对 I 的延续,倘若为任意二叉树,此前的方案是否还能实现?

说明:

    要求空间复杂度为 O(1)。

例如,给定下列的二叉树,

   	 1
       /  \
      2    3
     / \    \
    4   5    7

调用函数后,生成的树如下形式:

  	 1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \    \
    4-> 5 -> 7 -> NULL


分析:

    解法同 I,同样利用广度搜索。但是需要注意的是节点可能没有孩子,因此每行开始的位置不一定是最左端的孩子。因此,每次都要找到最左端起始节点,另外,中间节点也有可能没有孩子,所以需要一个记录每层中前面已经连接好的尾节点的指针,当找到同层下一个孩子时将其连接并后移。

class Solution {
public:
    void connect(TreeLinkNode *root) {
        if(!root)
        {
            return;
        }
        
        TreeLinkNode *pCurLevel = root;
        TreeLinkNode *pNextLevelStart = NULL, *pNextPre = NULL;
        while(pCurLevel)
        {
            pNextLevelStart = NULL;
            pNextPre = NULL;
            while(pCurLevel)//广度遍历,利用本层已经连接好的next链接下一层
            {
                if(!pCurLevel->left && !pCurLevel->right) //本层节点没有子树,则不连接,继续查询下一个节点
                {
                    pCurLevel = pCurLevel->next;
                }
                else //存在子树
                {
                    if(!pNextLevelStart)//下一层第一个节点
                    {
                        pNextLevelStart = pCurLevel->left ? pCurLevel->left : pCurLevel->right; //下一层开始位置
                    }
                    
                    if(pCurLevel->left && pCurLevel->right)//左右子树都有
                    {
                        pCurLevel->left->next = pCurLevel->right;//连接下一层
                        if(pNextPre)
                        {
                            pNextPre->next = pCurLevel->left;
                        }
                        pNextPre = pCurLevel->right;
                    }
                    else if(pCurLevel->left || pCurLevel->right)//只有一个子树
                    {
                        if(pNextPre)
                        {
                            pNextPre->next = pCurLevel->left ? pCurLevel->left : pCurLevel->right;
                            pNextPre = pNextPre->next;
                        }
                        else
                        {
                            pNextPre = pCurLevel->left ? pCurLevel->left : pCurLevel->right;
                        }
                    }
                    
                    pCurLevel = pCurLevel->next; //查找当前节点的下一个节点
                }
            }
            
            pCurLevel = pNextLevelStart; //指向下一层第一个节点
        }
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值