117. Populating Next Right Pointers in Each Node II

本文探讨了在二叉树中填充每个节点的next指针,使其指向其右侧相邻节点的方法。针对非完美二叉树,提出了两种解决方案:一种使用队列进行层级遍历,另一种采用迭代方式解决跨节点连接问题。文章详细分析了解决方案的实现细节及注意事项。
摘要由CSDN通过智能技术生成

https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/

Given a binary tree

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.

Example 1:

Input: root = [1,2,3,4,5,null,7]
Output: [1,#,2,3,#,4,5,7,#]
Explanation: Given the above 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:

  • The number of nodes in the given tree is less than 6000.
  • -100 <= node.val <= 100

算法思路:

与116第一种解法一样,在模拟levelOrder过程中添加next right pointer

class Solution {
public:
    Node* connect(Node* root) {
        if(root == NULL) return NULL;
        
        queue<Node*> que;
        que.push(root);
        Node* node = NULL;
        
        while(!que.empty()){
            int n = que.size();
            for(int i = 0; i < n; i++){
                if(i == 0){
                    node = que.front();
                    que.pop();
                }else{
                    node->next = que.front();
                    que.pop();
                    node = node->next;
                }
                if(node->left){
                    que.push(node->left);
                }
                if(node->right){
                    que.push(node->right);
                }
            }
        }
        
        return root;
    }
};

如果把116中的方法2直接搬过来非常的不合适,因为不是完美二叉树,next right pointer连接存在跨结点问题,且连接存在先后连接的问题,比如还是采用先序遍历,我们中间有些结点缺失导致左边结点连接到了右边(跨过根节点),由于先序遍历左根右,因此,左边连接完之前右边没有被连接,但是这个时候右边某个结点左右子节点都缺失,左边相连接过来,只可能连接到该缺失结点的下一节点的左结点或右结点(左结点为空时)...(点号表示这里存在递归或迭代情况,因为这个下一节点的左右孩子可能也为空),右边的递归和迭代走不下去,因为右边next right pointer尚未连接,因此左边结点指向的next right pointer 为NULL,但实际上右边只是尚未连接,不代表这一层的右边一定没有结点,因此之前的连接就是错误的,会遗失本层剩下的结点。

解决方式:连接好next right pointer之后,移动当前指针结点到next right pointer,接着从该节点继续往右连接,连接完本层,通过connect(getNextNode(root))连接下一层。

class Solution { 
private:
    Node* getNextNode(Node* node){
        while(node){
            if(node->left) return node->left;
            if(node->right) return node->right;
            node = node->next;
        }   
        return node;
    }   
public:
    Node* connect(Node* root) {
        if(!root) return root;
        
        Node* node = root;
        while(node){
            if(node->right){
			    if(node->left) node->left->next = node->right;
                    node->right->next = getNextNode(node->next);
		    }else if(node->left){
                node->left->next = getNextNode(node->next);
		    }
            node = node->next;
        }
		
        connect(getNextNode(root));
    
        return root;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值