[Leetcode] Populating next right pointer in each node ii 填充每个节点的右指针
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
这一题和上一题Populating next right pointer in each node的区别在于二叉树不是完美二叉树,所以每次的第一个结点不一定是沿着左子树的最左端一直向下。
方法一:
代码原出处没有解释,这里给出个人理解。上一题是这题的特殊情况,所以这题的代码也能通过上一题。
核心思想是:层次遍历。 在上一题中,我们记下当前行的下一行中最左端的结点作为起始点,是为了实现队列的层与层之间的转换功能,这里也同样用这种方式,但因上一题中是满二叉树,所以,我们只需在开头直接取就行,这里我们需判断当前行左右孩子中哪个存在就用哪个。这里值得注意的是,遇到4所在那一层时,cur=4的左右孩子都不存在时,直接取左右孩子中的一个,这时firNext依旧为NULL(因为不知道当前行中的左右孩子是否存在,所以,开始firNext定义为NULL),这时因为最左端的左右孩子都不存在,所以,不需要连接,然后我们在该行中移动cur,直达cur的左右孩子中至少一个存在,我们取存在的那个(若两个都存在,取左孩子)为下一行的最左端结点。
层与层之间的转换解决了,下面我们来解决行之间的移动。如图,若5为根结点的子树为3的右孩子,那如何连接4和5?像上一题中,4(身为2的左孩子),先连接2的右孩子,但其右孩子不存在啊?若是像上题中,那样:左连右,右连next的左,那中间就会有一个NULL !这时,我们定义一个遍历pre,让其完成在行中的穿针引线的作用:pre先指向2的左孩子4,因为2的右孩子不存在,所以,pre不动,直到遇到5.
最外层的while循环是层层之间的转化由firNext负责,层之间的连接由pre负责。

/**
* 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)
{
TreeLinkNode *cur=root;
while(cur)
{
TreeLinkNode *firNext=nullptr; //下一层的第一个结点
TreeLinkNode *prev=nullptr; //同一层中的前结点
while(cur)
{
if(firNext==nullptr)
firNext=cur->left?cur->left:cur->right;
if(cur->left)
{
if(prev)
prev->next=cur->left;
prev=cur->left;
}
if(cur->right)
{
if(prev)
prev->next=cur->right;
prev=cur->right;
}
cur=cur->next;
}
cur=firNext;
}
}
};
方法二:
递归,虽然不满题意,但有利于熟悉递归算法,依旧写在这。代码来源Grandyang博友。
// 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);
}
};
[Leetcode] Populating next right pointer in each node ii 填充每个节点的右指针的更多相关文章
- LeetCode: Populating Next Right Pointer in Each Node
LeetCode: Populating Next Right Pointer in Each Node Given a binary tree struct TreeLinkNode { TreeL ...
- LeetCode: Populating Next Right Pointers in Each Node II 解题报告
Populating Next Right Pointers in Each Node IIFollow up for problem "Populating Next Right Poin ...
- [LeetCode] Populating Next Right Pointers in Each Node II 每个节点的右向指针之二
Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...
- LeetCode——Populating Next Right Pointers in Each Node II
Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...
- [leetcode]Populating Next Right Pointers in Each Node II @ Python
原题地址:https://oj.leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/ 题意: Follow up ...
- [LeetCode] [LeetCode] Populating Next Right Pointers in Each Node II
Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...
- LeetCode - Populating Next Right Pointers in Each Node II
题目: Follow up for problem "Populating Next Right Pointers in Each Node". What if the given ...
- [Leetcode] Populating next right pointer in each node 填充每个节点的右指针
Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *nex ...
- LeetCode:Populating Next Right Pointers in Each Node I II
LeetCode:Populating Next Right Pointers in Each Node Given a binary tree struct TreeLinkNode { TreeL ...
随机推荐
- (四)启用HTTPS
安全规范中有一条是要求尽量使用https而弃用http(新Chrome将标记非HTTPS网站为不安全),其实启用https和之前的ipv6改造一样,并不是什么高难度或者工作流繁多的的改造,只需将中间件 ...
- mysql计算排名
mysql计算排名,获取行号rowno 学生成绩表数据 SELECT * FROM table_score ORDER BY score DESC; 获取某个学生成绩排名并计算该学生和上一名学生成绩差 ...
- Linux命令备忘录:mount用于加载文件系统到指定的加载点
mount命令用于加载文件系统到指定的加载点.此命令的最常用于挂载cdrom,使我们可以访问cdrom中的数据,因为你将光盘插入cdrom中,Linux并不会自动挂载,必须使用Linux mount命 ...
- 003---socket介绍
socket介绍 什么是socket? socket是应用层与tcp/ip协议族通信的中间软件抽象层,它是一组接口.在设计模式中.其实就是一个门面模式.我们无需深入理解tcp/udp协议,socket ...
- UVA11988 Broken Keyboard (a.k.a. Beiju Text)【数组模拟链表】
参考:https://blog.csdn.net/lianai911/article/details/41831645 #include <iostream> #include <c ...
- UVa Problem 100 The 3n+1 problem (3n+1 问题)
参考:https://blog.csdn.net/metaphysis/article/details/6431937 #include <iostream> #include <c ...
- FTP 主动模式与被动模式
项目中涉及到媒资传输的地方,均有ftp应用,而关于媒资传输故障的排查中,FTP主被动模式问题占了较高比例,但又容易被忽略, 特此收集相关资料介绍,同时整理了如何通wget.tcpdum分辨FTP的主被 ...
- Python标准库--inspect
inspect模块是针对模块,类,方法,功能等对象提供些有用的方法.例如可以帮助我们检查类的内容,检查方法的代码,提取和格式化方法的参数等. import inspect import os clas ...
- Git 查看远程分支、本地分支、删除本地分支及远程分支
1. 删除本地分支: git branch -d branchName 2. 删除远程分支: // 方法一:将删除的本地分支推到远程(要删除的远程分支在本地有映射) git push origin : ...
- 4364: [IOI2014]wall砖墙
4364: [IOI2014]wall砖墙 链接 分析: 线段树,维护一个最大值,一个最小值. 代码: #include<bits/stdc++.h> ],*p1 = buf,*p2 = ...