LC116 & 117 Populating Next Right Pointers in Each Node

 LC116.Populating Next Right Pointers in Each Node

给一个完美二叉树的节点添加一个指向右边下一个节点的指针

方法1:(递归)二叉树前序遍历,当前遍历到的点,如果左孩子存在,左孩子的 next 指向右孩子,此外,如果当前节点 next != NULL ,还需设置右孩子的 next 指针。

class Solution {
public:
    void dfs(Node* root) {
        if (root == NULL) return;
        if (root->left != NULL) {
            root->left->next = root->right;
            if (root->next) {
                root->right->next = root->next->left;
            }
        }
        dfs(root->left);
        dfs(root->right);
    }
    Node* connect(Node* root) {
        auto p = root;
        dfs(p);
        return root;
    }
};

 方法2:(迭代)二叉树的层序遍历,从根节点开始,设置好下一层的 next 指针,再从下一层开始,设置好下下一层的 next 指针,以此类推。

class Solution {
public:
    Node* connect(Node* root) {
        if (root == NULL) {
            return root;
        }
        auto pre = root, cur = pre;
        while (pre->left) {
            cur = pre;
            while (cur) {
                cur->left->next = cur->right;
                if (cur->next) cur->right->next = cur->next->left;
                cur = cur->next;
            }
            pre = pre->left;
        }
        return root;
    }
};

 LC117. Populating Next Right Pointers in Each Node II

同上题,但是二叉树是任意的。

方法1:(递归)还是二叉树的前序遍历,但是由于当前节点的孩子节点的 next 指针依赖于当前节点的 next 指针,因此当前节点的右边的所有 next 指针必须先设置好,所以先序遍历的顺序应该为:根节点$\Rightarrow$右孩子$\Rightarrow$左孩子。

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

 方法2:(迭代)还是二叉树的层序遍历,不同于第一题,遍历当前层时,需要记录下一层的第一个节点的位置,遍历完当前层后,从下一层第一个节点开始遍历。

class Solution {
public:
    Node* connect(Node* root) {
        Node *head = NULL, *prev = NULL, *cur = root;
        while (cur) {
            while (cur) {
                if (cur->left) {
                    if (prev) {
                        prev->next = cur->left;
                    }
                    else {
                        head = cur->left;
                    }
                    prev = cur->left;
                }
                if (cur->right) {
                    if (prev) {
                        prev->next = cur->right;
                    }
                    else {
                        head = cur->right;
                    }
                    prev = cur->right;
                }
                cur = cur->next;
            }
            cur = head;
            head = NULL;
            prev = NULL;
        }
        return root;
    }
};

上述方法可以用一个dummy节点,将两个循环变为一个,复杂度一样,但是代码更简洁:

class Solution {
public:
    Node* connect(Node* root) {
        Node* dummyHead = new Node(0); 
        Node* pre = dummyHead, *cur = root;
        while (cur) {
            if (cur->left) {
                pre->next = cur->left;
                pre = pre->next;
            }
            if (cur->right) {
                pre->next = cur->right;
                pre = pre->next;
            }
            cur = cur->next;
            if (cur == NULL) {
                pre = dummyHead;
                cur = pre->next;
                pre->next = NULL;
            }
        }
        return root;
    }
};

猜你喜欢

转载自www.cnblogs.com/betaa/p/12464484.html