这道题本来可以很简答,一个队列,存储指针和它的行数就OK了,但是这道题的难点在于不用额外空间复杂度。
横向看一下,这一行是不是就是一个链表呢?
多加一个变量,用来存储第一有有效节点,什么是有效节点呢?就是左右节点中至少有一个不为空的。这个节点为啥不存第一个节点呢?而是存第一个有效节点呢?其实对于这一行来说是没有区别的,但是对于下一行的使用是有区别的。
下面介绍第二个变量,叫做pre,每次遍历一个节点,都是让pre的next指向当前节点。既然这样,pre的默认值是无意义的。因为pre的next才是第一个有效节点。
给定一个二叉树
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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
/*
// 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;}
};