标签:
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:
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 每个节点的右向指针的延续,原本的完全二叉树的条件不再满足,但是整体的思路还是很相似,仍然有递归和非递归的解法。我们先来看递归的解法,这里由于子树有可能残缺,故需要平行扫描父节点同层的节点,找到他们的左右子节点。代码如下:
// Recursion, more than constant space class Solution { public: void connect(TreeLinkNode *root) { if (!root) return; TreeLinkNode *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; connect(root->right); connect(root->left); } };
对于非递归的方法,我惊喜的发现之前的方法直接就能用,完全不需要做任何修改,算法思路可参见之前的博客Populating Next Right Pointers in Each Node 每个节点的右向指针,代码如下:
// Non-recursion, more than constant space class Solution { public: void connect(TreeLinkNode *root) { if (!root) return; queue<TreeLinkNode*> q; q.push(root); q.push(NULL); while (true) { TreeLinkNode *cur = q.front(); q.pop(); if (cur) { cur->next = q.front(); if (cur->left) q.push(cur->left); if (cur->right) q.push(cur->right); } else { if (q.size() == 0 || q.front() == NULL) return; q.push(NULL); } } } };
虽然以上的两种方法都能通过OJ,但其实它们都不符合题目的要求,题目说只能使用constant space,可是OJ却没有写专门检测space使用情况的test,那么下面贴上constant space的解法,这个解法乍看上去蛮复杂,但是仔细分析分析也就那么回事了,首先定义了一个leftMost的变量,用来指向每一层最左边的一个节点,由于左子结点可能缺失,所以这个最左边的节点有可能是上一层某个节点的右子结点,我们每往下推一层时,还要有个指针指向上一层的父节点,因为由于右子节点的可能缺失,所以上一层的父节点必须向右移,直到移到有子节点的父节点为止,然后把next指针连上,然后当前层的指针cur继续向右偏移,直到连完当前层所有的子节点,再向下一层推进,以此类推可以连上所有的next指针,代码如下:
// Non-recursion, constant space class Solution { public: void connect(TreeLinkNode *root) { if (!root) return; TreeLinkNode *leftMost = root; while (leftMost) { TreeLinkNode *p = leftMost; while (p && !p->left && !p->right) p = p->next; if (!p) return; leftMost = p->left ? p->left : p->right; TreeLinkNode *cur = leftMost; while (p) { if (cur == p->left) { if (p->right) { cur->next = p->right; cur = cur->next; } p = p->next; } else if (cur == p->right) { p = p->next; } else { if (!p->left && !p->right) { p = p->next; continue; } cur->next = p->left ? p->left : p->right; cur = cur->next; } } } } };
[LeetCode] Populating Next Right Pointers in Each Node II 每个节点的右向指针之二
标签:
原文地址:http://www.cnblogs.com/grandyang/p/4290148.html