zoukankan      html  css  js  c++  java
  • 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;
        }
    };
  • 相关阅读:
    tuple 元组及字典dict
    day 49 css属性补充浮动 属性定位 抽屉作业
    day48 选择器(基本、层级 、属性) css属性
    day47 列表 表单 css初识
    day 46 http和html
    day 45索引
    day 44 练习题讲解 多表查询
    day 40 多表查询 子查询
    day39 表之间的关联关系、 补充 表操作总结 where 、group by、
    day38 数据类型 约束条件
  • 原文地址:https://www.cnblogs.com/betaa/p/12464484.html
Copyright © 2011-2022 走看看