每日一刷——12.10——学习二叉树解题模式(二)

题目三:填充每个节点的下一个右侧节点指针1

题目描述:116. 填充每个节点的下一个右侧节点指针 - 力扣(LeetCode)

我的理解:

我的感觉是同父亲还好搞一点,感觉是在遍历到每一个节点的时候,就把它的左孩子的next指针指向自己的右孩子,但是5和6之间应该咋搞比较好?我知道了,找到自己的next指向的节点,然后把它的左孩子给自己的右孩子的next

是这样么?

题目分析:

感觉可以浅浅鼓励一下自己哈哈哈,就素这样的思想,那么我们现在就要考虑咋写代码,由于我们要知道这是一个递归,我们按照什么逻辑能统一每一个节点要做的事

所以其实我们可以把这个二叉树看成一个三叉树,

===>怎么看成一个三叉树呢?就是把每两个相邻的节点看成是一个方框节点,那么就如下图:

 我们要统一的其实就是:

每个方框节点里边的两个圆圆节点,把他俩连接起来,好的,那么问题来了,怎么写代码???

题解:

其实我感觉就是传了两个节点了,就好搞一点了,所以关键就只是传两个节点,按照我的理解那里这样写代码:

嘻嘻,看一下我写的最后那里的注释

/*
// Definition for a Node.
class Node {
    public int val;
    public Node left;
    public Node right;
    public Node next;

    public Node() {}
    
    public Node(int _val) {
        val = _val;
    }

    public 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 ==null)
            return null;

        //遍历“三叉树”,连接相邻节点
        traverse(root.left , root.right);
        return root;

    }

    public static void traverse(Node node1,Node node2){
        if(node1==null ||node2 ==null)
            return;

        //前序位置
        //将传入的两个节点穿起来
        node1.next =node2;

        //连接相同父节点的两个子节点
        traverse(node1.left,node1.right);
        
        //soga!!!这样
        traverse(node1.left ,node1.right);
        traverse(node2.left ,node2.right);
        //连接跨域父节点的两个子节点
        traverse(node1.right, node2.left);

        //所以每一个节点都是做这样的事情,把传进来的连起来,先把它们看作一个整体,然后呢
        //就再把他们看成单独的,指导他们的孩子做什么
    }
}

 

题目四:填充每个节点的下一个右侧节点指针2

题目描述:117. 填充每个节点的下一个右侧节点指针 II - 力扣(LeetCode)

我的理解:

这个题目和上一题的区别好像就是,这里不是完全二叉树了

题目分析:

这里不能复用上面的代码,这里可以自己定义一个双端队列,按照按层遍历那里说的方法,把每一个节点拿出来

题解:

这里是运用的手写队列

/*
// Definition for a Node.
class Node {
    public int val;
    public Node left;
    public Node right;
    public Node next;

    public Node() {}
    
    public Node(int _val) {
        val = _val;
    }

    public 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 ==null){
            return root;
        }
        MyQueue queue =new MyQueue();
        queue.offer(root);
        while(!queue.isEmpty()){
            //第一个弹出的节点
            Node pre =null;
            int size =queue.size;
            for(int i=0;i<size;i++){
                Node cur =queue.poll();
                if(cur.left !=null){
                    queue.offer(cur.left);
                }
                if(cur.right !=null){
                    queue.offer(cur.right);
                }
                if(pre !=null){
                    pre.next =cur; //每次弹出的节点的next  指向下一个即可
                }
                pre =cur;
            }
        }

        return root;
    }

    public static class MyQueue{
        public Node head;
        public Node tail;
        public int size;

        public MyQueue(){
            head =null;
            tail =null;
            size=0;
        }

        public boolean isEmpty(){
            return size==0;
        }

        //在尾部加一个节点
        public void offer(Node cur){
            size++;
            if(head ==null){
                head =cur;
                tail =cur;
            }else{
                tail.next =cur;   //cur挂在尾巴上
                tail =cur ;    //cur变成新尾巴
            }
        }

        public Node poll(){
            size--;
            Node ans =head;  //记录头节点
            head =head.next;  //下一个节点变成头节点
            ans.next =null;   //断联
            return ans;
        }
    }
}

今天太晚了,明天再来这里详细写一下这个代码的思路!!我一定不会鸽吧----但是明天课有点多,可能后天更

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值