117. 填充每个节点的下一个右侧节点指针 II

常数空间复杂度解法

这道题是116的扩展版
本质就是层序遍历,原本要使用队列进行遍历,但是由于next指针的存在,层序遍历可以直接使用p = p->next实现
如果p的左右子节点均存在,则左节点的next指向右节点,而右节点的next需要指向p的next节点的左节点/右节点
于是需要单独维护p的下一层节点
如果是完全二叉树,则可以每次从root->left节点开始遍历,
而此题不是完全二叉树,不能通过上述方式访问到每一层的第一个节点
于是设置head节点指向p节点的下一层的第一个节点,head可以是任意值的一个节点
如何实现链接head节点和链接p的下一层节点的next指针?
需要设置tail节点,初始tail指向head
在遍历左右子节点的时候,更新tail和tai->next,
那么上述的规则就表示成
如果p节点的左节点存在,则tail->next指向左节点,再检查右节点如果存在,则tail->next指向右节点
相当于原来当前节点的左右节点设置转化成了整个这一层的“左右节点”即head指针和tail指针。
从而完成整个二叉树的next设置。

/*
// 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) {
        if(!root) return root;
        auto cur = root;
        while(cur){
            auto head = new Node(1);
            auto tail = head;
            for(auto p = cur; p; p = p->next){
                if(p->left) tail = tail->next = p->left;
                if(p->right) tail = tail->next = p->right;
            }
            cur = head->next;
        }
        return root;
    }
};

队列层序遍历通用解法

使用队列进行层序遍历,将下一层节点依次入队
一层一层处理next节点(体现在for(int i=0; i)

class Solution {
public:
    Node* connect(Node* root) {
        if(!root) return root;
        queue<Node*> q;
        q.push(root);
        while(!q.empty()){
            int n = q.size();
            Node *last = nullptr;
            for(int i=0; i<n; i++){
                Node *cur = q.front();
                q.pop();
                if(cur->left) q.push(cur->left);
                if(cur->right) q.push(cur->right);
                if(i!=0) last->next = cur;
                last = cur;
            }
        }
        return root;
    }
};

你可能感兴趣的:(LeetCode,算法,leetcode)