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;
        }
    };
  • 相关阅读:
    mikadonic负载均衡RH6(band)RH7(team)
    Linux日志系统两个分类:rsyslog和journal
    Linux7 重置root密码
    mikadonicLINUX文件系统大小调整
    文件系统fdisk、gdisk、parted
    Linux文件权限设置
    使用python3从零开始写安全脚本(1)
    浅谈软件开发企业绩效管理中的问题与对策(四、绩效方案实例)
    非常道中小软件公司项目管理(一 项目管理终极目标)
    浅谈软件开发企业绩效管理中的问题与对策(二、管理理论篇)
  • 原文地址:https://www.cnblogs.com/betaa/p/12464484.html
Copyright © 2011-2022 走看看