struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; }填充所有节点的next指针,指向最接近它的同一层右边节点。如果没有同一层没有右边的节点,则应该将next指针设置为NULL。
- 你只能使用常量级的额外内存空间
- 可以假设给出的二叉树是一个完美的二叉树(即,所有叶子节点都位于同一层,而且每个父节点都有两个孩子节点)。
struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; }填充所有节点的next指针,指向最接近它的同一层右边节点。如果没有同一层没有右边的节点,则应该将next指针设置为NULL。
//不能用递归 class Solution { public: void connect(TreeLinkNode *root) { if (!root) return; TreeLinkNode *p = root, *q; while (p->left) { q = p; while (q) { q->left->next = q->right; if (q->next) q->right->next = q->next->left; q = q->next; } p = p->left; } } };
class Solution { public: void connect(TreeLinkNode *root) { if (root == NULL) return; if (root->left!=NULL && root->right!=NULL) root->left->next = root->right; if (root->next != NULL &&root->right!=NULL){ root->right->next = root->next->left; } connect(root->left); connect(root->right); } };
import java.util.LinkedList; import java.util.Scanner; public class Solution { public void connect(TreeLinkNode root) { if (root== null) return; LinkedList<TreeLinkNode> queue = new LinkedList<>(); queue.offer(root); while (!queue.isEmpty()) { int length = queue.size(); //length存储的是目前这一层的长度 for (int i = 0; i < length; i++) { TreeLinkNode curNode = queue.poll(); if (i == length - 1) { //length表示是这一层最后一个节点,它的next为null curNode.next = null; }else { curNode.next = queue.peek(); } if(curNode.left != null) queue.offer(curNode.left); if(curNode.right != null) queue.offer(curNode.right); } } } }
//队列层次遍历 //一二问题都适用 void connect(TreeLinkNode *root) { if(root==NULL) return; TreeLinkNode *tail=root; TreeLinkNode *temp; queue<TreeLinkNode*> q; q.push(root); while(!q.empty()){ temp=q.front(); q.pop(); if(temp->left!=NULL) q.push(temp->left); if(temp->right!=NULL) q.push(temp->right); if(temp==tail){ temp->next=NULL; tail=q.back(); } else{ temp->next=q.front(); } } }
/**
* 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)
{
if(root!=NULL)
{ // 如果结点的左右孩子都存在,则让左孩子的 next 指向右孩子
if(root->left != NULL && root->right != NULL)
{
root->left->next = root->right;
}
// 如果结点的右侧有兄弟结点,并且兄弟结点的左孩子存在
// 则让该结点右孩子的 next 指向其兄弟结点的左孩子
if(root->next != NULL && root->next->left != NULL)
{
root->right->next = root->next->left;
}
// 递归处理左子树
connect(root->left);
// 递归处理右子树
connect(root->right);
}
}
};辅助队列 import java.util.Queue; import java.util.LinkedList; public class Solution { public void connect(TreeLinkNode root) { if(root==null) return; Queue<TreeLinkNode> q=new LinkedList<TreeLinkNode>(); q.add(root); q.add(null); while(!q.isEmpty()){ TreeLinkNode node=q.remove(); if(!q.isEmpty()){ node.next=q.peek(); if(node.left!=null) q.add(node.left); if(node.right!=null) q.add(node.right); if(q.peek()==null){ q.add(null); q.remove(); } } } } }
/** * 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) { if(root == null) return; //由于初值都是null,因此只需要把有next的找出来,变动即可 while(root.left != null){ TreeLinkNode node = root; while(node != null){ if(node.left != null) node.left.next = node.right;//完全二叉树,左子树有右子树就有 if(node.next != null) node.right.next = node.next.left; //从左到右遍历同层的所有节点 node = node.next; } //每次都从该层的最左边开始遍历 root = root.left; } } }
package day01; import java.util.LinkedList; import java.util.Queue; class Solution { public Node connect(Node root) { if (root == null) { return root; } // Initialize a queue data structure which contains // just the root of the tree Queue<Node> Q = new LinkedList<Node>(); Q.add(root); // Outer while loop which iterates over // each level while (Q.size() > 0) {//迭代树🌲的每一层 要队里还有元素就循环 // Note the size of the queue int size = Q.size();//队列中元素的个数 // Iterate over all the nodes on the current level for(int i = 0; i < size; i++) {//迭代每一层的每一个元素 // Pop a node from the front of the queue Node node = Q.poll();//队中的第一个元素出队 // This check is important. We don't want to // establish any wrong connections. The queue will // contain nodes from 2 levels at most at any // point in time. This check ensures we only // don't establish next pointers beyond the end // of a level if (i < size - 1) { node.next = Q.peek();//只要不是已经遍历到这一层最后一个元素 就把next指向队首元素,否则不执行 } // Add the children, if any, to the back of // the queue if (node.left != null) { Q.add(node.left); } if (node.right != null) { Q.add(node.right); } } } // Since the tree has now been modified, return the root node return root; } }
class Solution { public: void connect(TreeLinkNode *root) { if(!root)return; queue<TreeLinkNode*>que; que.push(root); TreeLinkNode* mostRight=root; while(!que.empty()){ TreeLinkNode* cur=que.front(); que.pop(); if(mostRight==cur)mostRight=cur->right; else cur->next=que.front(); if(cur->left)que.push(cur->left); if(cur->right)que.push(cur->right); } } };
class Solution { public: void connect(TreeLinkNode *root) { if(root == NULL) return; else connectNext(root); } void connectNext(TreeLinkNode *root) { if(root->left == NULL || root->right == NULL) return ; else { TreeLinkNode *l = root->left,*r = root->right; //对每层左子树最右结点和右子树最左结点进行连接 l->next = r; while(l->right != NULL && r->left != NULL) { l = l->right; r = r->left; l->next = r; } //对左子树和右子树进行递归 connectNext(root->left); connectNext(root->right); } } };
/* 首先,不能使用层次遍历的思路,因为不满足常量空间的限制(递归不纳入常量空间限制,在leetcode上的原题中有说明) 使用递归求解的思路: 对于一个设置好next值的节点node,若其左右节点均存在,则 其左儿子的next设为node的右儿子 右儿子的next分情况讨论: 若node->next不存在,则右儿子的next设为NULL 若node->next存在,则右儿子的next设为node->next->left 按照上述步骤遍历二叉树即可 */ class Solution { public: void connect(TreeLinkNode *root) { if(root == NULL || root -> left == NULL) return; // left son root -> left -> next = root -> right; // right son if(root -> next) root -> right -> next = root -> next -> left; connect(root -> left); connect(root -> right); return; } };
/** * 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) { /*法一 利用队列 层次遍历 即可 空间复杂度O(n) 先将右节点入队列,将上一次遍历的节点设为本次遍历节点的next即可 if(!root) return; queue<TreeLinkNode *> Q; Q.push(root); TreeLinkNode *pre=NULL; while(!Q.empty()){ int row_num = Q.size(); for(int i=0;i<row_num;i++){ TreeLinkNode *tmp = Q.front(); Q.pop(); tmp->next = pre; pre = tmp; if(tmp->right) Q.push(tmp->right); if(tmp->left) Q.push(tmp->left); } pre = NULL; } return; */ /*法二 不用层次遍历, 每次指针指向该层最左边,然后进行层次遍历,直到为NULL 下一次循环则指向下一层的最左边,依次下去.. */ if(!root) return; TreeLinkNode *p = root, *q; while(p->left!=NULL){ q = p; while(q!=NULL){ q->left->next = q->right; if(q->next!=NULL){ q->right->next = q->next->left; } q = q->next; } p = p->left; } return; } };
public class Solution { public void connect(TreeLinkNode root) { TreeLinkNode begin = root; while(root!=null&&root.left!=null) { if(root.next!=null) { root.left.next = root.right; root.right.next = root.next.left; root = root.next; } else { root.left.next=root.right; root = begin.left; begin = root; } } } }
// 层序遍历,每次从右往左遍历将上一次遍历节点设置为本次的next节点即可 public class Solution { public void connect(TreeLinkNode root) { if (root == null) { return; } Queue<TreeLinkNode> queue = new LinkedList<>(); queue.offer(root); TreeLinkNode pre = null; while (!queue.isEmpty()) { int size = queue.size(); while (size > 0) { TreeLinkNode node = queue.poll(); node.next = pre; pre = node; if (node.right != null) { queue.offer(node.right); } if (node.left != null) { queue.offer(node.left); } size--; } pre = null; } } }
public class Solution { public void connect(TreeLinkNode root) { if(root == null) return; if(root.left != null){ root.left.next = root.right; } if(root.next != null && root.left != null){ root.right.next = root.next.left; } connect(root.left); connect(root.right); } }
package populating_next_right_pointers_in_each_node;
import java.util.ArrayList;
/**
* 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 toNULL.
* 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
*/
public class Solution {
public class TreeLinkNode {
int val;
TreeLinkNode left, right, next;
TreeLinkNode(int x) { val = x; }
}
/**
* 树的层次遍历,由于使用了空间复杂度 O(n)
*/
public void connect1(TreeLinkNode root) {
if (root == null)
return;
ArrayList<TreeLinkNode> curLevel = new ArrayList<>();
curLevel.add(root);
while (!curLevel.isEmpty()) {
ArrayList<TreeLinkNode> nextLevel = new ArrayList<>();
// 遍历当前层
TreeLinkNode node = curLevel.get(0);
TreeLinkNode nextNode;
// 保存下一层节点
if (node.left != null) nextLevel.add(node.left);
if (node.right != null) nextLevel.add(node.right);
for (int i = 1; i < curLevel.size(); i++) {
// 修改 next 指针
nextNode = curLevel.get(i);
node.next = nextNode;
node = nextNode;
// 保存下一层节点
if (node.left != null)
nextLevel.add(node.left);
if (node.right != null)
nextLevel.add(node.right);
}
curLevel = nextLevel;
}
}
/**
* 递归的方式实现,空间复杂度为调用栈的深度
* 边界条件几种方式
* 1、root 为 null 直接返回
* 2、root 根节点下的左右子树的 next 链接
* 3、跨 root 根节点的子树的 next 链接
*/
public void connect2(TreeLinkNode root) {
if (root == null)
return;
// root 根节点下的左右子树的 next 链接
if (root.left != null && root.right != null)
root.left.next = root.right;
// 跨 root 根节点的子树的 next 链接
if (root.right != null && root.next != null)
root.right.next = root.next.left;
// 递归connect以root左右子树节点为根节点的子树
connect2(root.left);
connect2(root.right);
}
/**
* 非递归的方式实现
*
* 从最左边的节点开始更新 next 指针,同样两种情况:
* root.left.next -> root.right
* root.right.next -> root.next.left
*/
public void connect(TreeLinkNode root) {
if (root ==null)
return;
TreeLinkNode p = root;
TreeLinkNode updateRoot;
// 从根节点 p 开始,从最左边的节点开始修改p的下一层的左右子树节点的 next 指针
while (p.left != null) {
updateRoot = p;
while (updateRoot != null) {
// 第一种情况
updateRoot.left.next = updateRoot.right;
// 第二种情况
if (updateRoot.next != null) {
updateRoot.right.next = updateRoot.next.left;
}
// 更新的节点向右移动
updateRoot = updateRoot.next;
}
p = p.left;
}
}
}
/* * 推荐解答 */ public void connect(TreeLinkNode root) { TreeLinkNode level_start = root; while (level_start != null) { TreeLinkNode cur = level_start; while (cur != null) { if (cur.left != null) cur.left.next = cur.right; if (cur.right != null && cur.next != null) cur.right.next = cur.next.left; cur = cur.next; } level_start = level_start.left; } } /* * My Solution */ public void connect_2(TreeLinkNode root) { TreeLinkNode levelFirst = root; TreeLinkNode cur = levelFirst; while (cur != null) { if (cur.left != null) cur.left.next = cur.right; if (cur.right != null && cur.next != null) { cur.right.next = cur.next.left; } if (cur.next != null) cur = cur.next; else { levelFirst = levelFirst.left; cur = levelFirst; } } }