[LeetCode] 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:html

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.node

Initially, all next pointers are set to NULL.git

 

Example:github

Input: {"$id":"1","left":{"$id":"2","left":{"$id":"3","left":null,"next":null,"right":null,"val":4},"next":null,"right":{"$id":"4","left":null,"next":null,"right":null,"val":5},"val":2},"next":null,"right":{"$id":"5","left":{"$id":"6","left":null,"next":null,"right":null,"val":6},"next":null,"right":{"$id":"7","left":null,"next":null,"right":null,"val":7},"val":3},"val":1}

Output: {"$id":"1","left":{"$id":"2","left":{"$id":"3","left":null,"next":{"$id":"4","left":null,"next":{"$id":"5","left":null,"next":{"$id":"6","left":null,"next":null,"right":null,"val":7},"right":null,"val":6},"right":null,"val":5},"right":null,"val":4},"next":{"$id":"7","left":{"$ref":"5"},"next":null,"right":{"$ref":"6"},"val":3},"right":{"$ref":"4"},"val":2},"next":null,"right":{"$ref":"7"},"val":1}

Explanation: Given the above perfect binary tree (Figure A), your function should populate each next pointer to point to its next right node, just like in Figure B.

 

Note:app

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

這道題其實是樹的層序遍歷的應用,能夠參考以前的博客 Binary Tree Level Order Traversal,既然是遍歷,就有遞歸和非遞歸兩種方法,最好兩種方法都要掌握,都要會寫。下面先來看遞歸的解法,因爲是徹底二叉樹,因此若節點的左子結點存在的話,其右子節點一定存在,因此左子結點的 next 指針能夠直接指向其右子節點,對於其右子節點的處理方法是,判斷其父節點的 next 是否爲空,若不爲空,則指向其 next 指針指向的節點的左子結點,若爲空則指向 NULL,代碼以下:ide

 

解法一:post

class Solution {
public:
    Node* connect(Node* root) {
        if (!root) return NULL;
        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);
        return root;
    }
};

 

對於非遞歸的解法要稍微複雜一點,但也不算特別複雜,須要用到 queue 來輔助,因爲是層序遍歷,每層的節點都按順序加入 queue 中,而每當從 queue 中取出一個元素時,將其 next 指針指向 queue 中下一個節點便可,對於每層的開頭元素開始遍歷以前,先統計一下該層的總個數,用個 for 循環,這樣當 for 循環結束的時候,該層就已經被遍歷完了,參見代碼以下:this

 

解法二:url

// Non-recursion, more than constant space
class Solution {
public:
    Node* connect(Node* root) {
        if (!root) return NULL;
        queue<Node*> q;
        q.push(root);
        while (!q.empty()) {
            int size = q.size();
            for (int i = 0; i < size; ++i) {
                Node *t = q.front(); q.pop();
                if (i < size - 1) {
                    t->next = q.front();
                }
                if (t->left) q.push(t->left);
                if (t->right) q.push(t->right);
            }
        }
        return root;
    }
};

 

咱們再來看下面這種碉堡了的方法,用兩個指針 start 和 cur,其中 start 標記每一層的起始節點,cur 用來遍歷該層的節點,設計思路之巧妙,不得不服啊:spa

 

解法三:

// Non-recursion, constant space
class Solution {
public:
    Node* connect(Node* root) {
        if (!root) return NULL;
        Node *start = root, *cur = NULL;
        while (start->left) {
            cur = start;
            while (cur) {
                cur->left->next = cur->right;
                if (cur->next) cur->right->next = cur->next->left;
                cur = cur->next;
            }
            start = start->left;
        }
        return root;
    }
};

 

Github 同步地址:

https://github.com/grandyang/leetcode/issues/116

 

相似題目:

Populating Next Right Pointers in Each Node II

Binary Tree Right Side View

 

參考資料:

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

https://leetcode.com/problems/populating-next-right-pointers-in-each-node/discuss/37473/My-recursive-solution(Java)

https://leetcode.com/problems/populating-next-right-pointers-in-each-node/discuss/37472/A-simple-accepted-solution

 

LeetCode All in One 題目講解彙總(持續更新中...)

相關文章
相關標籤/搜索