代码随想录算法训练营第十五天| 层序遍历,226.翻转二叉树,101.对称二叉树

层序遍历

层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。

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

而这种层序遍历方式就是图论中的广度优先遍历,只不过应用在二叉树上。

LeetCode 102. 二叉树的层序遍历

借用队列结构实现,代码较为简单:

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        if(root == null) return result;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()) {
            int count = queue.size();
            List<Integer> res = new ArrayList<Integer>();
            while(count != 0) {
                TreeNode top = queue.poll();
                if(top.left != null) queue.offer(top.left);
                if(top.right != null) queue.offer(top.right);
                res.add(top.val);
                count--;
            }
            result.add(res);
        }
        return result;
    }
}

LeetCode 107.二叉树的层次遍历 II

相对于102.二叉树的层序遍历,就是最后把result数组反转一下就可以了。代码如下:

lass Solution {
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        if(root == null) return result;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()) {
            int count = queue.size();
            List<Integer> res = new ArrayList<Integer>();
            while(count != 0){
                TreeNode top = queue.poll();
                if(top.left != null) queue.offer(top.left);
                if(top.right != null) queue.offer(top.right);
                res.add(top.val);
                count--;
            }
            result.add(res);
        }
        Collections.reverse(result);
        return result;
    }
}

LeetCode 199.二叉树的右视图

最开始没理解到位题目的意思,写的思路是只将结点的右孩子入队列,提交时样例没过。看了题解才知道人家的意思是求每一层最后一个结点,修改后代码如下:

class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> result = new ArrayList<Integer>();
        if(root == null) return result;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()) {
            int count = queue.size();
            for(int i=0; i<count; i++){
                TreeNode top = queue.poll();
                if(i == (count - 1)) result.add(top.val);
                if(top.left != null) queue.offer(top.left);
                if(top.right != null) queue.offer(top.right);
            }
        }
        return result;
    }
}

LeetCode 637.二叉树的层平均值

本题就是层序遍历的时候把一层求个总和在取一个均值。注意类型的定义,代码如下:

class Solution {
    public List<Double> averageOfLevels(TreeNode root) {
        List<Double> result = new ArrayList<Double>();
        if(root == null) return result;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()) {
            int count = queue.size();
            double sum = 0;
            for(int i=0; i<count; i++) {
                TreeNode top = queue.poll();
                sum += top.val;
                if(top.left != null) queue.offer(top.left);
                if(top.right != null) queue.offer(top.right);
            }
            result.add(sum / count);
        }
        return result;
    }
}

LeetCode 429.N叉树的层序遍历

这道题依旧是模板题,只不过一个节点有多个孩子了。代码如下:

class Solution {
    public List<List<Integer>> levelOrder(Node root) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        if(root == null) return result;
        Queue<Node> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()) {
            int count = queue.size();
            List<Integer> res = new ArrayList<Integer>();
            while(count != 0) {
                Node top = queue.poll();
                res.add(top.val);
                count--;
                if(top.children == null || top.children.size() == 0) continue;
                for(Node child:top.children) {
                    if(child != null) {
                        queue.offer(child);
                    }
                }
            }
            result.add(res);
        }
        return result;
    }
}

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

层序遍历,取每一层的最大值。代码如下:

class Solution {
    public List<Integer> largestValues(TreeNode root) {
        List<Integer> result = new ArrayList<Integer>();
        if(root == null) return result;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()) {
            int count = queue.size();
            int max = Integer.MIN_VALUE;;
            while(count != 0) {
                TreeNode top = queue.poll();
                if(top.left != null) queue.offer(top.left);
                if(top.right != null) queue.offer(top.right);
                if(top.val > max) {
                    max = top.val;
                }
                count--;
            }
            result.add(max);
        }
        return result;
    }
}

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

本题依然是层序遍历,只不过在单层遍历的时候记录一下本层的头部节点,然后在遍历的时候让前一个节点指向本节点就可以了。代码如下:

class Solution {
    public Node connect(Node root) {
        if(root == null) return root;
        Queue<Node> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()) {
            int count = queue.size();
            Node front = queue.poll();
            if(front.left != null) queue.offer(front.left);
            if(front.right != null) queue.offer(front.right);
            while(count != 1) {
                Node top = queue.poll();
                if(top.left != null) {
                    queue.offer(top.left);
                }
                if(top.right != null) queue.offer(top.right);
                front.next = top;
                front = top;
                count--;
            }
        }
        return root;
    }
}

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

这道题目说是二叉树,但116题目说是完整二叉树,其实没有任何差别,一样的代码一样的逻辑一样的味道。

LeetCode 104.二叉树的最大深度

最大的深度就是二叉树的层数,采用层序遍历然后记录层数返回即可。代码如下:

class Solution {
    public int maxDepth(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        if(root == null) return 0;
        queue.offer(root);
        int result = 0;
        while(!queue.isEmpty()) {
            int count = queue.size();
            result++;
            while(count != 0) {
                TreeNode top = queue.poll();
                if(top.left != null) queue.offer(top.left);
                if(top.right != null) queue.offer(top.right);
                count--;
            }
        }
        return result;
    }
}

LeetCode 111.二叉树的最小深度

层序遍历时,判断一下当前结点是否为叶子结点,如果是则返回当前的深度,不是则继续遍历。代码如下:

class Solution {
    public int minDepth(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        if(root == null) return 0;
        queue.offer(root);
        int result = 0;
        while(!queue.isEmpty()) {
            int count = queue.size();
            result++;
            while(count != 0) {
                TreeNode top = queue.poll();
                if(top.left == null && top.right == null) return result;
                if(top.left != null) queue.offer(top.left);
                if(top.right != null) queue.offer(top.right);
                count--;
            }
        }
        return result;
    }
}

总结

二叉树的层序遍历,就是图论中的广度优先搜索在二叉树中的应用,需要借助队列来实现,上面10个题基本是用一份代码模版来做的,还比较简单。

LeetCode 226.翻转二叉树

递归遍历时,可采用前序和后序,中序遍历代码有点绕。题目还是比较简单的,前序遍历代码如下:

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

LeetCode 101. 对称二叉树

什么是对称二叉树呢?若左子树和右子树可以相互翻转,则称该二叉树为对称二叉树。

此题采用后序遍历,为啥用后序遍历呢?因为需要收集左结点和右结点的信息返回给父节点。

最后需要注意一下递归处理返回值的情况不要漏掉,代码如下:

class Solution {
    public boolean isSymmetric(TreeNode root) {
        return compare(root.left, root.right);
    }
    public boolean compare(TreeNode left, TreeNode right) {
        if(left == null && right != null) {
            return false;
        } else if(left != null && right == null) {
            return false;
        }else if(left == null && right == null) {
            return true;
        }else if(left.val != right.val) {
            return false;
        }
        boolean outside = compare(left.left, right.right);
        boolean inside = compare(left.right, right.left);
        return outside && inside;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值