Given a binary tree
struct TreeLinkNode {
TreeLinkNode *left;
TreeLinkNode *right;
TreeLinkNode *next;
}
Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL
.
Initially, all next pointers are set to NULL
.
Note:
- You may only use constant extra space.
- You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).
For example,
Given the following perfect binary tree,
1
/ \
2 3
/ \ / \
4 5 6 7
After calling your function, the tree should look like:
1 -> NULL
/ \
2 -> 3 -> NULL
/ \ / \
4->5->6->7 -> NULL
第一个题的要求是完全二叉树,第二题没有这个要求。很显然如果没有空间复杂度的要求,O(1),这题完全可以按层次遍历的思想搞,又提到了工具方法的概念,可以先看这道题:http://blog.youkuaiyun.com/my_jobs/article/details/47665089按层次遍历。完全可以改造这个题而成。但是这两个题都要求空间复杂度为O(1)。所以此办法不行,但是可以给出代码,对这两个题完全通用:
public void connect(TreeLinkNode root) {
if (root == null) return;
LinkedList<TreeLinkNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
int len = queue.size();
TreeLinkNode pre = null;
for (int i = 0; i < len; i++) {
TreeLinkNode node = queue.poll();
if (i == 0) {
pre = node;
} else {
pre.next = node;
pre = pre.next;
}
if (node.left != null) queue.add(node.left);
if (node.right != null) queue.add(node.right);
}
}
}
可以看出,上面的代码完全是改造出来的,所以一些常见的算法,一定烂熟于心。
先做第一个,比较好做。看代码就明白了:
public void connect(TreeLinkNode root) {
if (root == null) return;
root.next = null;
while (root.left != null) {
TreeLinkNode p = root;
while (p != null) {
p.left.next = p.right;
if (p.next != null) {
p.right.next = p.next.left;
} else {
p.right.next = null;
}
p = p.next;
}
root = root.left;
}
}
这个的精髓就是,在层次迭代的时候,一定要有效的利用已经搭建好的东西,比如next指针。
在看第二道题,第二题就难了。
public void connect(TreeLinkNode root) {
while(root != null){
TreeLinkNode childHead = new TreeLinkNode(0);
TreeLinkNode p = childHead;
while (root != null){
if (root.left != null) {
p.next = root.left;
p = p.next;
}
if (root.right != null) {
p.next = root.right;
p = p.next;
}
root = root.next;
}
p.next = null;
root = childHead.next;
}
}
此题比较秒的就是每层的头指针,太巧妙了。利用了链表性质!!!
改造题:
Given the following binary tree,
1
/ \
2 3
\ / \
5 6 7
After calling your function, the tree should look like:
1 -> NULL
/
2 -> 3 -> NULL
/
5->6->7 -> NULL
树的数据结构不变,如果当前节点是本层首个节点的话,left指针指向下层首节点,否则为空。right指针指向本层的下一个节点。万能的解法,层次遍历:
public TreeNode treeToList(TreeNode root) {
if (root == null) return null;
LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
TreeNode head = new TreeNode(0);
while (!queue.isEmpty()) {
int len = queue.size();
TreeNode pre = null;
for (int i = 0; i < len; i++) {
TreeNode node = queue.poll();
if (node.left != null) queue.add(node.left);
if (node.right != null) queue.add(node.right);
node.left = null;
node.right = null;
if (i == 0) {
pre = node;
head.left = pre;
head = head.left;
} else {
pre.right = node;
pre = pre.right;
}
}
}
return root;
}
相比上面两道题有next指针可以利用,这个有没有了,必须先本下层的节点都保存了才能修改本层的节点关系!!!