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

题目

给定一个二叉树

struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

初始状态下,所有 next 指针都被设置为 NULL。

思路

从上一题完美二叉树进一步,需要额外判断各个子节点存在与否,再选择如何给next赋值。
初步的想法是在完美二叉树的代码基础上,通过if语句的判断利用递归实现问题。发现代码书写过于复杂,而且没有想到使用next==nullptr去纵向判断。参考解析,着重记录下代码写法,使用三目运算符逻辑操作符简洁的进行表示:

class Solution {
public:
    Node* connect(Node* root) {
        if(root and (root->left or root->right)){//root节点存在且至少存在一个子节点。
            //两个子节点同时存在时,可以直接给next赋值
            if(root->left and root->right) root->left->next = root->right;
            //需要两个父节点之间的子节点进行next操作,优先为right,不存在咋为left(right和left至少存在一个)
            //学习利用三目运算符用简洁的代码 表示带判断后的选择!!!!!!!!!!!
            Node *node = root->right ? root->right : root->left;
            //要进行父节点下的子节点next操作,需保证root->next至少存在子节点
            //初始化需要操作的父节点,即找到存在子节点的父节点进行next操作
            Node *head = root->next;
            while (head and not (head->left or head->right)){//root->next存在,但是没子节点时继续指向下一个next
                head = head->next;//保证head是同一层中存在子节点的同级节点,没有则 为nullptr且退出循环
            }
            //对子节点进行next操作,首先需确保有两个父节点,有的话在判断是父节点的哪个左右子节点(若都不存在则为nullptr),双重三目运算符
            node->next = head ? (head->left ? head->left : head->right) : nullptr;
            //先对右子节点进行next操作
            connect(root->right);
            connect(root->left);
        }
        return root;
    }
};

借此题,重温下递归的操作:
明白一个函数的作用并相信它能完成这个任务,千万不要试图跳进细节!
递归的思想是某个函数直接或间接地调用自身,这样把原问题的求解转换成很多性质相同但是规模更小的子问题上。需要关注如何把原问题划分为
两个特征:结束条件和自我调用
结束条件:在本题中当父节点不存在或者父节点无子节点则会挨个退出。
自我调用:传递子问题。

想不到用嵌套的三目运算符,可以通过if来判断:

class Solution {
public:
    Node* connect(Node* root) {
        connect(root, nullptr);
        return root;
    }

    void connect(Node* root, Node* next) {
        if (root == nullptr) {
            return;
        }
        root->next = next;
        Node* p = nullptr;
        if(root->right != nullptr){
            p = root->next;
            while(p != nullptr){
                if(p->left != nullptr){
                    p = p->left;
                    break;
                }
                if(p->right != nullptr){
                    p = p->right;
                    break;
                }
                p = p->next;
            }
            connect(root->right, p);
            connect(root->left, root->right);
        }else{
            p = root-> next;
            while(p != nullptr){
                if(p->left != nullptr){
                    p = p->left;
                    break;
                }
                if(p->right != nullptr){
                    p = p->right;
                    break;
                }
                p = p->next;
            }
            connect(root->left, p);
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值