1. 程式人生 > >[LeetCode] 117. Populating Next Right Pointers in Each Node II

[LeetCode] 117. Populating Next Right Pointers in Each Node II

Populating Next Right Pointers in Each Node II

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.
Recursive approach is fine, implicit stack space does not count as extra space for this problem.
Example:


Given the following binary tree,
這裡寫圖片描述

解析

類似於[LeetCode] 116. Populating Next Right Pointers in Each Node,只是現在不能保證二叉樹是滿二叉樹。

解法1:佇列

這個解法跟[LeetCode] 116. Populating Next Right Pointers in Each Node裡的佇列解法完全一樣。

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

解法2:遞迴

先找到同一層root的next節點,利用next進行依次尋找left和right,找到root的子節點next應該連結的節點,重點是先遞迴右子樹,後遞迴左子樹

class Solution {
public:
    void connect(TreeLinkNode *root) {
        if (!root) return;
        TreeLinkNode* cur = root->next;
        while(cur){
            if(cur->left){
                cur = cur->left;
                break;
            }
            if(cur->right){
                cur = cur->right;
                break;
            }
            cur = cur->next;
        }
        if(root->right) root->right->next = cur;
        if(root->left) root->left->next = root->right ? root->right : cur;
        connect(root->right);
        connect(root->left);
    }
};

解法3:構建函式

構建一個尋找下一層first節點的函式

    void connect(TreeLinkNode * root){
        if(!root) return;
        TreeLinkNode* cur;
        while(root){
            cur = root;
            while(cur){
                if(cur->left && cur->right){
                    cur->left->next = cur->right;
                    cur->right->next = getnextlevelFirst(cur->next);
                }
                else if(cur->left || cur->right){
                    getnextlevelFirst(cur)->next = getnextlevelFirst(cur->next);
                }
                cur = cur->next;
            }
            root = getnextlevelFirst(root);
        }
    }

    TreeLinkNode* getnextlevelFirst(TreeLinkNode* root){  //構建一個尋找下一層第一個節點的函式。
        if(!root) return NULL;
        else if(root->left) return root->left;
        else if(root->right) return root->right;
        else return getnextlevelFirst(root->next);
    }

解法4:空間複雜度O(1)

建立一個dummy結點來指向每層的首結點的前一個結點,然後指標t用來遍歷這一層,我們實際上是遍歷一層,然後連下一層的next,首先從根結點開始,如果左子結點存在,那麼t的next連上左子結點,然後t指向其next指標;如果root的右子結點存在,那麼t的next連上右子結點,然後t指向其next指標。此時root的左右子結點都連上了,此時root向右平移一位,指向其next指標,如果此時root不存在了,說明當前層已經遍歷完了,我們重置t為dummy結點,root此時為dummy->next,即下一層的首結點,然後dummy的next指標清空。

class Solution {
public: 
    void connect(TreeLinkNode *root) {
        if (!root) return;
        TreeLinkNode* dummy = new TreeLinkNode(0);
        TreeLinkNode* t = dummy;
        while(root){
            if(root->left){
                t->next = root->left;
                t = t->next;
            }
            if(root->right){
                t->next = root->right;
                t = t->next;
            }
            root = root->next;
            if(!root){
                t = dummy;
                root = dummy->next;
                dummy->next = NULL;
            }
        }
    }
};

參考

http://www.cnblogs.com/grandyang/p/4290148.html