LeetCode 116. 填充每个节点的下一个右侧节点指针(Java代码)

题目

在这里插入图片描述
在这里插入图片描述

提示:

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

题目连接

思路

这一道题目很容易审题错误,像我,我就依据上面的那张图,认定只要让一个节点 左孩子连上右孩子, 让左孩子的右孩子 连上 右孩子的左孩子 就可以了。

然而它给我们展示的图片是没有包含所有情况的,例如下边这种情况:

二叉树的层数非常多的时候,就会碰到麻烦。

在这里插入图片描述

上面的 11 和 12 使用一般方法无法连接上

还有,如果两个节点中间有几个空的节点(不好意思,搞错了!!!,题目没看清,每一个父节点都有两个子节点。哎哟!)

但是还是留在这里,当作个审题眼睛没看清的记号吧。

在这里插入图片描述

层次遍历法(使用队列)

其实总容易想到的就是层序遍历了,只要将每一层的节点存入队列中。

然后,每一次取出每一层的数据,进行连接,特别方便。但是题目要求不允许这样使用:

/*
    先试用队列来做吧
*/

class Solution {
    public Node connect(Node root) {
        if(root == null) return null;
        Queue<Node> queue = new LinkedList<Node>();
        queue.offer(root);
        Node prev;
        while(!queue.isEmpty()){
            prev = null;
            int size = queue.size();
            while(size-->0){
                Node node = queue.poll();
                // 让右边先入队列,这样左边出队列的时候,它的 prev就是右边(右边先出队列),可以直接 left.next = prev(right)
                if(node.right != null) queue.offer(node.right);
                if(node.left != null) queue.offer(node.left);
                node.next = prev;
                prev = node;
            }
        }
        return root;
    }
}

这样的空间复杂度不满足题目要求(常数级)

层次遍历法(使用递归)

因此,使用一下层次遍历的递归,这样就不用创建一个队列了

/*
    DFS,先递归到最右,然后让这个 node指向 prev(prev=null),然后让prev==null。
   	第一次递归到该层的时候,往 levels添加元素,之后每一层对应的节点从 levels根据 level下标取出,
   	上一次存入的 prev,用 next指向它之后,将自己赋值为 prev
*/

class Solution {
    List<Node> levels = new ArrayList<Node>();
    public Node connect(Node root) {
        connect(root, 0);
        return root;
    }
    public void connect(Node root, int level){
        if(root == null) return;
        if(level >= levels.size()){
            // 每一层第一次进入的时候,初始化每一层为 null,
            levels.add(null);
        }
        
        Node node = levels.get(level);
        root.next = node;
        levels.set(level, root);
        
        connect(root.right, level+1);
        connect(root.left, level+1);
    }
}

空间复杂度应该是 O(H),H是二叉树的层数。依旧不满足常数级的要求

没辙了,那几个特殊情况太难解决了。只能求助题解区大佬了。

无敌是多么寂寞

class Solution {
    // 这无敌的代码
    public Node connect(Node root) {
        dfs(root, null);
        return root;
    }

    private void dfs(Node node, Node next) {
        if(node != null) {
        	// 这一步是连接上一级别传入的,左右孩子
            node.next = next;
            // 这一步是让此节点的左右孩子,相互连接
            dfs(node.left, node.right);
            // 下面画图理解
            dfs(node.right, node.next != null ? node.next.left : null);
        }
    }
}

在这里插入图片描述

画了图的话,还是比较容易做出来的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值