Populating Next Right Pointers in Each Node II -- leetcode

来源:互联网 发布:淘宝缠论指标知道 编辑:程序博客网 时间:2024/05/23 10:28

Follow up for problem "Populating Next Right Pointers in Each Node".

What if the given tree could be any binary tree? Would your previous solution still work?

Note:

  • You may only use constant extra space.

For example,
Given the following binary tree,

         1       /  \      2    3     / \    \    4   5    7

After calling your function, the tree should look like:

         1 -> NULL       /  \      2 -> 3 -> NULL     / \    \    4-> 5 -> 7 -> NULL


基本思路:

和 Populating Next Right Pointers in Each Node 一样,以当前结点为一个处理单位,

1. 将右子树的结点挂到左子树的next上;

2. 将右邻居的左子树结点,持到当前结点right子树上的next上。


但,

和 Populating Next Right Pointers in Each Node 相比,缺少的条件是,不再是一个完全二叉树了。

不能简单的通过从root结点出发,延着left指针,找到每层链表头了。

故当完成上一个层次的链接后,还需要一定的措施,找到下一层的起始点。

方法之一,就是延着上一层的next指针,找到第一个left 或者 right不为空的结点。顺着该结点,就找到了下一层起始点。

另外一个不同点是,将右邻居的left子树,挂到当前结点的right子树的next上时,右邻居,可能没有left,甚至也没有right。那么就只能延着next一种搜索下去,找到第一个有孩子的结点。将其孩子串到当前结点的子树的next上。


此代码在leetcode上实际执行时间为43ms。

/** * Definition for binary tree with next pointer. * struct TreeLinkNode { *  int val; *  TreeLinkNode *left, *right, *next; *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {} * }; */class Solution {public:    void connect(TreeLinkNode *root) {        while (root && (root->left || root->right)) {            TreeLinkNode *p = root;            while (p) {                TreeLinkNode *tail = 0;                if (p->left && p->right) {                    p->left->next = p->right;                    tail = p->right;                }                else if (p->left)                    tail = p->left;                else                    tail = p->right;                                TreeLinkNode *q = p->next;                while (q && !q->left && !q->right)                    q = q->next;                                if (q)                    tail->next = q->left ? q->left : q->right;                                    p = q;            }                        root = root->left ? root->left: root->right;            while (root && !root->left && !root->right)                root = root->next;        }    }};



上面的写法还是点麻烦,

在内层循环中,建立一个伪链表头,指向树下一层串起来链表的表头。

当完成该层串接后,只要通过该链表头,就可以找到向一层的起始结点。

在内层循环过层中,维持一指向链表尾元素的指针,可以方便的把left 和右子树串起来。变成了一个普通的链表尾部的添加元素操作。

在代码在leetcode上实际执行时间为38ms。
class Solution {public:    void connect(TreeLinkNode *root) {        while (root) {            TreeLinkNode head(0);            TreeLinkNode *tail = &head;            while (root) {                if (root->left) {                    tail->next = root->left;                    tail = tail->next;                }                if (root->right) {                    tail->next = root->right;                    tail = tail->next;                }                root = root->next;            }            root = head.next;        }    }

此代码参考自:

https://leetcode.com/discuss/24398/simple-solution-using-constant-space

0 0
原创粉丝点击