给定一个二叉树
struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; }
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL
。
初始状态下,所有 next 指针都被设置为 NULL
。
说明:
- 你只能使用额外常数空间。
- 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
- 你可以假设它是一个完美二叉树(即所有叶子节点都在同一层,每个父节点都有两个子节点)。
示例:
给定完美二叉树,
1 / \ 2 3 / \ / \ 4 5 6 7
调用你的函数后,该完美二叉树变为:
1 -> NULL / \ 2 -> 3 -> NULL / \ / \ 4->5->6->7 -> NULL
解题思路:
完美二叉树,加上他们的兄弟指针。二叉树中的兄弟就是同一层的结点。从根结点开始,他的兄弟为空指针(NULL),让他的左孩子指向右孩子,右孩子指向他兄弟的左孩子。很显然从上而下,每一层访问完就从下一层的第一个结点开始,直到所有兄弟访问完就可以继续下一层。最后所有层都访问完即可。
一开始没有注意,完全二叉树的特点,采用了层次遍历的方法,多用了一个队列,16ms。后来领悟了某些大神的12ms代码,就有了以上的感悟。但是层次遍历也有可取之处,当树不是完全二叉树的时候,也同样适用。
#define hasLChild(x) (!(x->left==NULL)) #define hasRChild(x) (!(x->right==NULL)) class Solution { public: void connect(TreeLinkNode *root) { queue<TreeLinkNode*> Q; if (root == NULL) return; int size; Q.push(root); TreeLinkNode* temp; while (!Q.empty()) { size = Q.size(); for (int i = 1; i <= size; i++) { temp = Q.front(); Q.pop(); if (hasLChild(temp)) Q.push(temp->left); if (hasRChild(temp)) Q.push(temp->right); if (i == size) {temp->next = NULL;break;} temp->next = Q.front(); } } } }; |
class Solution { public: void connect(TreeLinkNode *root) { if (!root) return; TreeLinkNode *start = root, *cur = NULL; while (start->left) { cur = start; while (cur) { cur->left->next = cur->right; if (cur->next) cur->right->next = cur->next->left; cur = cur->next; } start = start->left; } } }; |
用本人所写的C++代码,同样也能完成Leetcode:117.填充同一层的兄弟节点II。