题目116:
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 toNULL
.
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分析(原创-非递归):
/**
* Definition for binary tree with next pointer.
* public class TreeLinkNode {
* int val;
* TreeLinkNode left, right, next;
* TreeLinkNode(int x) { val = x; }
* }
*/
public class Solution {
public void connect(TreeLinkNode root) {
//给定满二叉树,指出每个节点是否存在右兄弟节点,如果存在,则指出,否则为null
//思路:层序遍历该二叉树,判断是否存在右兄弟节点
if(root==null) return ;
Queue<TreeLinkNode> oddQueue=new LinkedList <>();
Queue<TreeLinkNode> evenQueue=new LinkedList <>();
oddQueue.add(root);
int count=1;
while(!oddQueue.isEmpty()||!evenQueue.isEmpty()){
//奇数
while(count%2==1&&!oddQueue.isEmpty()){
//当前处理的节点
TreeLinkNode temp=oddQueue.poll();
//如果不是叶子节点
if(temp.left!=null){
temp.left.next=temp.right;
//判断该节点是否该层最后一个节点,如果是最后一个不指向兄弟节点的孩子
if(!oddQueue.isEmpty()){
//不是最后一个,讲该节点的右孩子指向右兄弟的左孩子
temp.right.next=oddQueue.peek().left;
}
evenQueue.add(temp.left);
evenQueue.add(temp.right);
}
}
//偶数
while(count%2==0&&!evenQueue.isEmpty()){
TreeLinkNode temp=evenQueue.poll();
//如果不是叶子节点
if(temp.left!=null){
temp.left.next=temp.right;
//判断该节点是否该层最后一个节点,如果是最后一个不指向兄弟节点的孩子
if(!evenQueue.isEmpty()){
//不是最后一个,讲该节点的右孩子指向右兄弟的左孩子
temp.right.next=evenQueue.peek().left;
}
oddQueue.add(temp.left);
oddQueue.add(temp.right);
}
}
count++;
}
}
}
分析2(参考答案-递归):
/**
* Definition for binary tree with next pointer.
* public class TreeLinkNode {
* int val;
* TreeLinkNode left, right, next;
* TreeLinkNode(int x) { val = x; }
* }
*/
public class Solution {
public void connect(TreeLinkNode root) {
//给定满二叉树,指出每个节点是否存在右兄弟节点,如果存在,则指出,否则为null
//思路:递归对左右子树进行右兄弟进行处理
if(root==null) return ;
if(root.left!=null){
root.left.next=root.right;
//判断是否是最后一个
if(root.next!=null){
root.right.next=root.next.left;
}
}
//递归
connect(root.left);
connect(root.right);
}
}
题目117:
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分析:
/**
* Definition for binary tree with next pointer.
* public class TreeLinkNode {
* int val;
* TreeLinkNode left, right, next;
* TreeLinkNode(int x) { val = x; }
* }
*/
public class Solution {
public void connect(TreeLinkNode root) {
//给定任意二叉树,找出各节点的next指向其右兄弟节点,如果不存在,则null
//思路:因为每一层节点都指向右兄弟节点,不管是否是相邻的,所以需要使用队列来容纳各层结构
if(root==null) return ;
Queue<TreeLinkNode> oddQu=new LinkedList<>();
Queue<TreeLinkNode> evenQu=new LinkedList<>();
oddQu.add(root);
int count=1;
while(!oddQu.isEmpty()||!evenQu.isEmpty()){
//奇数
while(count%2==1&&!oddQu.isEmpty()){
TreeLinkNode temp=oddQu.poll();
if(!oddQu.isEmpty()){
//如果该层还有节点
temp.next=oddQu.peek();
}
if(temp.left!=null)
evenQu.add(temp.left);
if(temp.right!=null)
evenQu.add(temp.right);
}
//偶数
while(count%2==0&&!evenQu.isEmpty()){
TreeLinkNode temp=evenQu.poll();
if(!evenQu.isEmpty()){
//如果该层还有节点
temp.next=evenQu.peek();
}
if(temp.left!=null)
oddQu.add(temp.left);
if(temp.right!=null)
oddQu.add(temp.right);
}
count++;
}
}
}
分析(参考答案):
/**
* Definition for binary tree with next pointer.
* public class TreeLinkNode {
* int val;
* TreeLinkNode left, right, next;
* TreeLinkNode(int x) { val = x; }
* }
*/
public class Solution {
public void connect(TreeLinkNode root) {
//给定任意二叉树,找出各节点的next指向其右兄弟节点,如果不存在,则null
//思路:采用类似链表的结构,来遍历整个树
if(root==null) return ;
TreeLinkNode dummy=new TreeLinkNode(0);
//用来标记当前尾节点
TreeLinkNode cur=dummy;
while(root!=null){
if(root.left!=null){
//拼接
cur.next=root.left;
cur=cur.next;
}
if(root.right!=null){
cur.next=root.right;
cur=cur.next;
}
//待处理的下一个根节点
root=root.next;
//判断是否为空,如果为空,则从链表中取出新的根节点
if(root==null){
root=dummy.next;
//重置初始化节点
cur=dummy;
dummy.next=null;
}
}
}
}