116、117填充每个节点的下一个右侧节点指针I、II(leetcode)

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

题目描述

题目链接:116 117
116和117题目类似,都是要填充每个结点的 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。(初始状态下,所有 next 指针都被设置为 NULL。)
例:
在这里插入图片描述
不同的是116为完美二叉树,而117为普通二叉树。

解题思路

刚看题目描述,肯定是不太清楚是什么意思。其实就是二叉树的每个结点定义时就有一个next指针,我们所需要做的就是改变next指针的指向。
比如116题的完美二叉树的定义:

// 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) {}
};

完美二叉树

抓住两点。

  • 一个结点的左孩子的 next 指针指向该结点的右孩子。
  • 一个结点的右孩子的 next 指针指向该结点的 next 结点的左孩子。
root->left->next=root->right;
if(root->next) //判断条件要有
root->right->next=root->next->left;

二叉树

摘自:C++ O(1)空间 简洁 递归
与完美二叉树不同的是,可能一个结点没有孩子,可能有一个孩子。
对于任意一次递归,只考虑如何设置子节点的 next 属性,分为三种情况:

  • 没有子节点:直接返回
  • 有一个子节点:将这个子节点的 next 属性设置为同层的下一个节点,即为 root.next 的最左边的一个节点,如果 root.next 没有子节点,则考虑 root.next.next,依次类推
  • 有两个节点:左子节点指向右子节点,然后右子节点同第二种情况的做法

注意递归的顺序需要从右到左。我的理解:因为在这段代码的时候是从左到右寻找满足条件的结点,所以递归时要从右到左完成了结点的next指针后才能继续寻找。

 while(nextnode&&!nextnode->left&&!nextnode->right)
            nextnode=nextnode->next;

代码

完美二叉树

class Solution {
public:
    Node* connect(Node* root) {
        if(!root||!root->left) return root;//root->left为空表示是叶子结点
        root->left->next=root->right;
        if(root->next) //判断条件要有
            root->right->next=root->next->left;
        connect(root->left);
        connect(root->right);
        return root;
    }
};

二叉树

class Solution {
public:
    Node* connect(Node* root) {
        if(!root||(!root->left&&!root->right)) return root;//空的,注意‘ !’
        if(root->left&&root->right)root->left->next=root->right;//root有两个结点
        //root有一个结点
        Node* child=root->right? root->right:root->left;
        Node* nextnode= root->next;
        //找到root的右边节点中第一个有子节点的那个节点
        while(nextnode&&!nextnode->left&&!nextnode->right)//这句话的意思:nextnode不为空且没有孩子 那么我就得继续寻找结点
            nextnode=nextnode->next;
        child->next=nextnode?(nextnode->left?nextnode->left:nextnode->right):NULL;
	    //必须保证右边节点的next已经被操作过,因此是从右子树到左子树的前序遍历
        connect(root->right);
        connect(root->left);
        return root;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值