116. Populating Next Right Pointers in Each Node

116. Populating Next Right Pointers in Each Node

题目

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.

Note:

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

方法1: recursion

思路:

recursion要思考的问题是,在每一层需要解决什么问题?1. 自己的left和right要打通,2. 如果有next,right和next -> left要打通。通过这一点就已经完成了下一层所有节点的打通,而下层的事情交给孩子们去处理。这是一个必须遵循preorder的栗子,因为下面的实现依靠本层先打通下一层。

// 注意if判断条件之间的关系
// 题目要求:You may only use constant extra space.
class Solution {
public:
    Node* connect(Node* root) {
        if (!root) return root;
        
        if (root -> left) {
        	root -> left -> next = root -> right;
        }
        if (root -> right && root -> next) {
        	root -> right -> next = root -> next -> left;
        }
        connect(root -> left);
        connect(root -> right);
        return root;
    }
};

方法2: iterative

思路:

如何在O(1)的空间下实现遍历?本来iterative的方法是一定要借用stack的,才能回去找到后面的路,但是这里由于在遍历上一层的时候已经打通了本层的next,所以stack不必要,O(1)变为可能。每一层在已经打通的情况下要如何打通下一层?首先用一个cur遍历本层,在每一个节点cur必须负责1. 自己 cur -> left -> next = cur -> right 的打通,2. 以及如果有cur -> next的情况下,cur -> right -> next = cur -> left 的打通。完成后可以后移cur。第二个问题, 如果没有queue的情况下,如何发起下一层的遍历?因此必须要求在每次cur在最初发起本层遍历的时候,预先委托一个变量newStart记住这个下层起始,也就是cur -> left。cur每次接过newStart,newStart被向下遣派,循环也以此为标记终止:如果newStart 的位置为null,循环结束。

Complexity

Time complexity: O(n)
Space complexity: O(1)

易错点:

  1. cur -> left 查空
  2. cur -> next 查空

From discussion

class Solution {
public:
    Node* connect(Node* root) {
        // if (!root || !root -> left) return root;
        Node* cur = root;
        Node* newStart = root;
        while (newStart) {
            cur = newStart;
            while (cur) {
                if (cur -> left){
                    cur -> left -> next = cur -> right;
                    if (cur -> next) cur -> right -> next = cur -> next -> left;
                    cout << cur -> val << endl;
                }
                cur = cur -> next;
            }
            newStart = newStart -> left;
        }
        return root;
    }
};

Java

void connect(TreeLinkNode *root) {
       TreeLinkNode* level_start = root;
       
       while(level_start!=NULL)
       {
           //curr is the first node in that level
           TreeLinkNode* curr = level_start;
           
           //Keep going to the right in that level
           while(curr!=NULL)
           {
               if(curr->left!=NULL) curr->left->next=curr->right;
               if(curr->right!=NULL && curr->next!=NULL) curr->right->next=curr->next->left;
               
               curr = curr->next;
           }
           level_start=level_start->left;
       }
       
   }

方法3

层序遍历

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值