代码随想录算法训练营第十五天 |二叉树

102. 二叉树的层序遍历

给你二叉树的根节点 root,返回其节点值的 层序遍历。 (即逐层地,从左到右访问所有节点)。

输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]

对于二叉树的层序遍历,需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。

解题思路:

  1. 定义一个二维列表用来存储最终结果
  2. 定义队列
  3. 将root添加到队列当中
  4. 如果队列不为空,设置一个一维列表用来存储二叉树每一层的遍历结果,计算二叉树的层数,每一层分别去遍历,从左往右
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> reslut=new ArrayList<>();
        Deque<TreeNode> que=new LinkedList<>();
        if(root==null){
            return reslut;
        }
        que.offer(root);
        while(!que.isEmpty()){
            List<Integer> res=new ArrayList<>();
            int size=que.size();
            while(size>0){
                TreeNode node=que.poll();
                res.add(node.val);
                if(node.left!=null){
                    que.offer(node.left);
                }
                if(node.right!=null){
                    que.offer(node.right);
                }
                size--;
            }
            reslut.add(res);
        }
        return reslut;

    }
}

107. 二叉树的层序遍历 II

给你二叉树的根节点 root,返回其节点值 自底向上的层序遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

输入:root = [3,9,20,null,null,15,7]
输出:[[15,7],[9,20],[3]]

107和102类似,思路可以使将结果保存到链表当中,依旧按照层序遍历,但是每一层的结果都加到链表的最前面

LinkedList<List<Integer>> result=new LinkedList<>();

class Solution {
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        LinkedList<List<Integer>> result=new LinkedList<>();
        Deque<TreeNode> deq=new LinkedList<>();
        if(root==null){
            return result;
        }
        deq.offer(root);
        while(!deq.isEmpty()){
            List<Integer> res=new ArrayList<>();
            int size=deq.size();
            for(int i=0;i<size;i++){
                TreeNode node=deq.poll();
                res.add(node.val);
                if(node.left!=null){
                    deq.offer(node.left);
                }
                if(node.right!=null){
                    deq.offer(node.right);
                }
            }
            result.addFirst(res);
        }
        return result;

    }
}

199. 二叉树的右视图

给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

输入: [1,2,3,null,5,null,4]
输出: [1,3,4]

这道题主要要判断每一层的最后一个元素,将其添加到结果列表当中

class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> reslut=new ArrayList<>();
        Deque<TreeNode> deq=new LinkedList<>();
        if(root==null){
            return reslut;
        }
        deq.offer(root);
        while(!deq.isEmpty()){
            int size=deq.size();
            while(size>0){
                TreeNode node=deq.poll();
                if(node.left!=null){
                    deq.offer(node.left);
                }
                if(node.right!=null){
                    deq.offer(node.right);
                }
                if(size==1){
                    reslut.add(node.val);
                }
                size--;
            }
        }
        return reslut;

    }
}

637. 二叉树的层平均值

给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5以内的答案可以被接受。

输入:root = [3,9,20,null,null,15,7]
输出:[3.00000,14.50000,11.00000]

将每一层的元素均相加,但是这里要注意除的size需要提前备份,不然每次while循环在减少

class Solution {
    public List<Double> averageOfLevels(TreeNode root) {
        List<Double> reslut=new ArrayList<>();
        Deque<TreeNode> deq=new LinkedList<>();
        if(root==null){
            return reslut;
        }
        deq.offer(root);
        while(!deq.isEmpty()){
            int size=deq.size();
            int len=size;
            double temp=0.0;
            while(len-->0){
                TreeNode node=deq.poll();
                temp+=node.val;
                if(node.left!=null){
                    deq.offer(node.left);
                }
                if(node.right!=null){
                    deq.offer(node.right);
                }
            }
            reslut.add(temp/size);
        }
        return reslut;
    }
}

429. N 叉树的层序遍历

给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。

树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。

输入:root = [1,null,3,2,4,null,5,6]
输出:[[1],[3,2,4],[5,6]]

这道题的不同点在于,每个结点有N个子结点,所以需要遍历结点里面的所有子结点

class Solution {
    public List<List<Integer>> levelOrder(Node root) {
        List<List<Integer>> reslut=new ArrayList<>();
        Deque<Node> que=new LinkedList<>();
        if(root==null){
            return reslut;
        }
        que.offer(root);
        while(!que.isEmpty()){
            List<Integer> res=new ArrayList<>();
            int size=que.size();
            while(size-->0){
                Node cur=que.poll();
                res.add(cur.val);
                for(Node next:cur.children){
                    que.offer(next);
                }

            }
            reslut.add(res);
        }
        return reslut;
        
    }
}

515.在每个树行中找最大值

给定一棵二叉树的根节点 root,请找出该二叉树中每一层的最大值。

输入: root = [1,3,2,5,3,null,9]
输出: [1,3,9]
class Solution {
    public List<Integer> largestValues(TreeNode root) {
        List<Integer> reslut=new ArrayList<>();
        Deque<TreeNode> que=new LinkedList<>();
        if(root==null){
            return reslut;
        }
        que.offer(root);
        while(!que.isEmpty()){
            int size=que.size();
            int max=que.getFirst().val;
            while(size-->0){
                TreeNode node=que.poll();
                max=Math.max(max,node.val);
                if(node.left!=null){
                    que.offer(node.left);
                }
                if(node.right!=null){
                    que.offer(node.right);
                }
            }
            reslut.add(max);
        }
        return reslut;
    }
}

104.二叉树的最大深度

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

class Solution {
    public int maxDepth(TreeNode root) {
        Deque<TreeNode> que=new LinkedList<>();
        if(root==null){
            return 0;
        }
        que.offer(root);
        int depth=0;
        while(!que.isEmpty()){
            int size=que.size();
            while(size-->0){
                TreeNode node=que.poll();
                if(node.left!=null){
                    que.offer(node.left);
                }
                if(node.right!=null){
                    que.offer(node.right);
                }
            }
              depth++;
            
        }
        return depth;
    }
}

111. 二叉树的最小深度

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

输入:root = [3,9,20,null,null,15,7]
输出:2

和求最大深度相比,最小深度需要判断node的左右节点均为空。

class Solution {
    public int minDepth(TreeNode root) {
        Deque<TreeNode> que=new LinkedList<>();
        if(root==null){
            return 0;
        }
        que.offer(root);
        int depth=0;
        while(!que.isEmpty()){
            int size=que.size();
            depth++;
            while(size-->0){
                TreeNode node=que.poll();
                if(node.left==null&&node.right==null){
                    return depth;
                }
                if(node.left!=null){
                    que.offer(node.left);
                }
                if(node.right!=null){
                    que.offer(node.right);
                }
            }
        }
        return depth;

    }
}

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

给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL

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

输入:root = [1,2,3,4,5,6,7]
输出:[1,#,2,3,#,4,5,6,7,#]

在遍历的过程中修改每个节点的 next\text{next}next 指针,同时拓展下一层的新队列。

class Solution {
    public Node connect(Node root) {
         if(root==null) return root;
        Deque<Node> deq=new LinkedList<>();
        deq.offer(root);
        while(!deq.isEmpty()){
            int size=deq.size();
            for(int i=0;i<size;i++){
                Node node=deq.poll();
                if(i<size-1){
                    node.next=deq.peek();
                }
                if(node.left!=null){
                    deq.offer(node.left);
                }
                if(node.right!=null){
                    deq.offer(node.right);
                }
            }
        }
        return root;
    }
}

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

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL 。

输入:root = [1,2,3,4,5,null,7]
输出:[1,#,2,3,#,4,5,7,#]
class Solution {
    public Node connect(Node root) {
         Queue<Node> que=new LinkedList<>();
        if(root==null) return root;
        que.offer(root);
        while(!que.isEmpty()) {
            int size = que.size();
            for(int i=0;i<size;i++){
                Node node=que.poll();
                if(i==size-1){
                    node.next=null;
                }else{
                    Node new1=que.peek();
                    node.next=new1;
                }
                if(node.left!=null) que.offer(node.left);
                if(node.right!=null) que.offer(node.right);
            }
        }
        return root;
    }
}

226. 翻转二叉树

给你一棵二叉树的根节点 root,翻转这棵二叉树,并返回其根节点。

输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]

思路一:BFS

class Solution {
    public TreeNode invertTree(TreeNode root) {
        Deque<TreeNode> deq=new LinkedList<>();
        if(root==null) return root;
        deq.offer(root);
        while(!deq.isEmpty()){
            int size=deq.size();
            while(size-->0){
                TreeNode node=deq.poll();
                swap(node);
                if(node.left!=null) deq.offer(node.left);
                if(node.right!=null) deq.offer(node.right);
            }
        }
        return root;
    }
    public void swap(TreeNode root){
        TreeNode temp=root.left;
        root.left=root.right;
        root.right=temp;
    }
}

思路二:递归

class Solution {
   public TreeNode invertTree(TreeNode root) {
        if(root==null) return root;
        invertTree(root.left);
        invertTree(root.right);
        swap(root);
        return root;
    }
    public void swap(TreeNode root){
        TreeNode temp=root.left;
        root.left=root.right;
        root.right=temp;
    }
}

101. 对称二叉树

给你一个二叉树的根节点 root, 检查它是否轴对称。

输入:root = [1,2,2,3,4,4,3]
输出:true

思路一:递归

将root的左右节点分别进行递归比较

class Solution {
    public boolean isSymmetric(TreeNode root) {
        return comparable(root.left,root.right);
    }
    public boolean comparable(TreeNode left,TreeNode right){
        if (left == null && right != null) {
            return false;
        }
        if (left != null && right == null) {
            return false;
        }

        if (left == null && right == null) {
            return true;
        }
        if (left.val != right.val) {
            return false;
        }
        boolean ouside=comparable(left.left,right.right);
        boolean inside=comparable(left.right,right.left);
        return ouside&&inside;
    }
}

思路二:BFS

class Solution {
   public boolean isSymmetric(TreeNode root) {
        return compara(root,root);
    }
    public boolean compara(TreeNode root1,TreeNode root2){
        Deque<TreeNode> deq=new LinkedList<>();
        deq.offer(root1);
        deq.offer(root2);
        while(!deq.isEmpty()){
            root1=deq.poll();
            root2=deq.poll();
            if(root1==null&&root2==null){
                continue;
            }
            if((root1==null||root2==null)||(root1.val!=root2.val)){
                return false;
            }
            deq.offer(root1.left);
            deq.offer(root2.right);
            deq.offer(root1.right);
            deq.offer(root2.left);
        }
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值