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

给定一个二叉树

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

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

 

进阶:

你只能使用常量级额外空间。
使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。

解题思路:

这一题使用多余的辅助空间就是使用队列来层次遍历,不需要考虑空的情况,比较简单,就不写了

如果是用递归的话,就需要注意每一次遍历这一层来进行连接的时候,一定得确保上一层是连接好了的;所以递归的时候不能先深度遍历左节点,而是要先遍历右节点,确保上一层是连接好了的,这样再深度遍历下一层的左节点的时候才能确保上一层的右节点全是连接好了的(因为有隔空的情况),这里我后来调试递归的时候想到了,但是我的代码写的有点冗余,于是我觉得直接迭代会更加简单。

先贴一下别人递归的解法:

public class Solution {
    public Node connect(Node root) {
        if (root == null || (root.right == null && root.left == null)) {
            return root;
        }
        if (root.left != null && root.right != null) {
            root.left.next = root.right;
            root.right.next = getNextNoNullChild(root);
        }
        if (root.left == null) {
            root.right.next = getNextNoNullChild(root);
        }
        if (root.right == null) {
            root.left.next = getNextNoNullChild(root);
        }

        //这里要注意:先递归右子树,否则右子树根节点next关系没建立好,左子树到右子树子节点无法正确挂载
        root.right = connect(root.right);
        root.left = connect(root.left);

        return root;
    }

    /**
     * 一路向右找到有子节点的根节点
     */
    private static Node getNextNoNullChild(Node root) {
        while (root.next != null) {
            if (root.next.left != null) {
                return root.next.left;
            }
            if (root.next.right != null) {
                return root.next.right;
            }
            root = root.next;
        }
        return null;
    }
}

我的解法是直接迭代:

class Solution {
public:

    Node* connect(Node* root) {
        if(!root)
            return NULL;
        Node* leftMost=root->left;
        Node* n=NULL;
        Node *rn=NULL;
        Node* cur=root;
        int i = 0;
        while(cur)
        {
            n = cur->next;
            rn=NULL;
                while(n)   //确保找到隔空的next节点
                {
                    rn=(n->left)?n->left:n->right;
                    if(rn)
                        break;  
                    else
                    n=n->next; 
                }
            if(i==0)    //找到下一层遍历的开始节点
            {
                if(cur->left)
                {
                    leftMost=cur->left;
                    i=1;
                }else if(cur->right)
                {
                    leftMost=cur->right;
                    i=1;
                }
            }
            if(cur->left&&cur->right)
            {
                cur->left->next=cur->right;
                cur->right->next=rn;
            }else if(cur->left&&!cur->right)
            {
                cur->left->next=rn;
            }
            else if(cur->right)
                cur->right->next=rn;
            if(cur->next)
                cur=cur->next;  //这一层的next节点
            else
            {
                cur=leftMost;   //这一层结束,从下一层开始
                leftMost=NULL;
                i=0;
            }   
        }
        return root;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值