文章目录
- 1. 背
- 2. 题目
- 3. 答案
1. 背
这道题本来可以很简答,一个队列,存储指针和它的行数就OK了,但是这道题的难点在于不用额外空间复杂度。
横向看一下,这一行是不是就是一个链表呢?
多加一个变量,用来存储第一有有效节点,什么是有效节点呢?就是左右节点中至少有一个不为空的。这个节点为啥不存第一个节点呢?而是存第一个有效节点呢?其实对于这一行来说是没有区别的,但是对于下一行的使用是有区别的。
下面介绍第二个变量,叫做pre,每次遍历一个节点,都是让pre的next指向当前节点。既然这样,pre的默认值是无意义的。因为pre的next才是第一个有效节点。
2. 题目
给定一个二叉树
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/populating-next-right-pointers-in-each-node-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
3. 答案
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node* next;
Node() : val(0), left(NULL), right(NULL), next(NULL) {}
Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}
Node(int _val, Node* _left, Node* _right, Node* _next)
: val(_val), left(_left), right(_right), next(_next) {}
};
*/
class Solution {
public:
Node* connect(Node* root) {
auto lastList = root;///<第一个有效节点
while(nullptr!=lastList)
{
auto node = lastList;
Node preNode(-1);
auto pre = &preNode;///<所有的赋值都是从pre开始的,因此第一个pre是无效的。
while(nullptr!=node)//遍历链表
{
if(node->left!=nullptr)
{
pre->next = node->left;
pre = pre->next;
}
if(node->right!=nullptr)//<这里没用else if就很灵性,因为遍历是以节点为单位的,但是left还有可能要指向right
{
pre->next = node->right;
pre = pre->next;
}
node = node->next;
}
/*寻找下一个有效节点*/
while(lastList!=nullptr && lastList->left==nullptr && lastList->right==nullptr)
lastList = lastList->next;
if(lastList==nullptr)
break;
lastList = lastList->left==nullptr ? lastList->right:lastList->left;
}
return root;
}
};