二叉树遍历9道题

目录

107.二叉树的层序遍历Ⅱ

1.解题思路

2.我的实现

实现遇到的问题

代码

代码中的错误

3.标准实现

区别

4.题目总结

199.二叉树的右视图

1.解题思路

2.我的实现

代码

3.标准实现

4.题目总结

637.二叉树的层平均值

1.解题思路

2.我的实现

3.标准实现

429.N叉树的层序遍历

1.解题思路

2.我的实现

3.标准实现

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

1.解题思路

2.我的实现

实现遇到的问题

求列表中的最大值

代码

3.标准实现

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

1.解题思路

2.我的实现

3.标准实现

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

104.二叉树的最大深度

1.解题思路

2.我的实现

3.标准实现

111.二叉树的最小深度

1.解题思路

2.我的实现

实现遇到的问题

代码

3.标准实现

区别


107.二叉树的层序遍历Ⅱ

题目链接:二叉树的层序遍历Ⅱ

1.解题思路

1.将每层得到的列表用栈收集,再将栈pop出来用最后的列表收集

2.我的实现

实现遇到的问题

代码

public List<List<Integer>> res=new ArrayList<>();

    public Stack<List<Integer>> tmpstack=new Stack<>();
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        levelOrderfun2(root);
        return res;
    }
    public void levelOrderfun2(TreeNode root){
        if (root==null){
            return;
        }
        Queue<TreeNode> queue=new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()){
            List<Integer> tmpres=new ArrayList<>();
            int size= queue.size();

            while (size>0){
                TreeNode tmp=queue.poll();
                tmpres.add(tmp.val);
                if (tmp.left!=null){
                    queue.add(tmp.left);
                }
                if (tmp.right!=null){
                    queue.add(tmp.right);
                }

                size--;
            }
            //用栈收集每个列表,后进先出
            tmpstack.push(tmpres);

        }
        //用列表收集最后结果
        while (!tmpstack.isEmpty()){
            res.add(tmpstack.pop());
        }
    }

代码中的错误

3.标准实现

public class N0107 {

    /**
     * 解法:队列,迭代。
     * 层序遍历,再翻转数组即可。
     */
    public List<List<Integer>> solution1(TreeNode root) {
        List<List<Integer>> list = new ArrayList<>();
        Deque<TreeNode> que = new LinkedList<>();

        if (root == null) {
            return list;
        }

        que.offerLast(root);
        while (!que.isEmpty()) {
            List<Integer> levelList = new ArrayList<>();

            int levelSize = que.size();
            for (int i = 0; i < levelSize; i++) {
                TreeNode peek = que.peekFirst();
                levelList.add(que.pollFirst().val);

                if (peek.left != null) {
                    que.offerLast(peek.left);
                }
                if (peek.right != null) {
                    que.offerLast(peek.right);
                }
            }
            list.add(levelList);
        }

        List<List<Integer>> result = new ArrayList<>();
        for (int i = list.size() - 1; i >= 0; i-- ) {
            result.add(list.get(i));
        }

        return result;
    }
}

区别

4.题目总结

199.二叉树的右视图

题目链接:二叉树的右视图

1.解题思路

层序遍历这个二叉树,取每层最后一个元素

定义变量接收时,每一个就要在层循环(一个层里面)里面,每一层就要在层循环外面

2.我的实现

代码

 public List<Integer> result=new ArrayList<>();
    public List<Integer> rightSideView(TreeNode root) {
        rightSideViewfunc(root);

        return result;
    }
    public void rightSideViewfunc(TreeNode root){
        if (root==null){
            return;
        }
        Queue<TreeNode> queue=new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()){

            //每一层的大小
            int size= queue.size();
            //遍历每一层的所有节点
            while (size>0){
                //接收每一个节点
                TreeNode tmp=new TreeNode();
                //每进来一个就要推出
                tmp=queue.poll();
                //当为最后一个节点时就收集
                if (size==1){
                    result.add(tmp.val);
                }
                if (tmp.left!=null){
                    queue.offer(tmp.left);
                }
                if (tmp.right!=null){
                    queue.offer(tmp.right);
                }
                size--;

            }
        }
    }

3.标准实现

public class N0199 {
    /**
     * 解法:队列,迭代。
     * 每次返回每层的最后一个字段即可。
     *
     * 小优化:每层右孩子先入队。代码略。
     */
    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        Deque<TreeNode> que = new LinkedList<>();

        if (root == null) {
            return list;
        }

        que.offerLast(root);
        while (!que.isEmpty()) {
            int levelSize = que.size();

            for (int i = 0; i < levelSize; i++) {
                TreeNode poll = que.pollFirst();

                if (poll.left != null) {
                    que.addLast(poll.left);
                }
                if (poll.right != null) {
                    que.addLast(poll.right);
                }

                if (i == levelSize - 1) {
                    list.add(poll.val);
                }
            }
        }

        return list;
    }
}

4.题目总结

637.二叉树的层平均值

题目链接:二叉树的层平均值

1.解题思路

遍历每一层的节点,节点的值用一个double收集,并加入sum中,遍历完一层后求平均并加入最终列表中

2.我的实现

 public List<Double> averageOfLevels(TreeNode root) {
        
        List<Double> res=new ArrayList<>();

        if (root==null){
            return null;
        }
        Queue<TreeNode> queue=new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()){
            //需要算每一层的就放在每一层的层序遍历外面
            Double sumdouble=0.0;
            int tmpInt;
            TreeNode tmpTreeNode=new TreeNode();
            int size= queue.size();
            int tmpSize=size;
            while (tmpSize>0){
                tmpTreeNode=queue.poll();
                tmpInt=tmpTreeNode.val;
                sumdouble+=tmpInt;
                if (tmpTreeNode.left!=null){
                    queue.add(tmpTreeNode.left);
                }
                if (tmpTreeNode.right!=null){
                    queue.add(tmpTreeNode.right);
                }
                tmpSize--;
            }
            //一层遍历完之后,计算平均数
            Double avg=sumdouble/size;
            res.add(avg);
        }
        
        return res;
    }

3.标准实现

// 637. 二叉树的层平均值
public class N0637 {

    /**
     * 解法:队列,迭代。
     * 每次返回每层的最后一个字段即可。
     */
    public List<Double> averageOfLevels(TreeNode root) {
        List<Double> list = new ArrayList<>();
        Deque<TreeNode> que = new LinkedList<>();

        if (root == null) {
            return list;
        }

        que.offerLast(root);
        while (!que.isEmpty()) {

            int levelSize = que.size();
            double levelSum = 0.0;
            for (int i = 0; i < levelSize; i++) {
                TreeNode poll = que.pollFirst();

                levelSum += poll.val;

                if (poll.left != null) {
                    que.addLast(poll.left);
                }
                if (poll.right != null) {
                    que.addLast(poll.right);
                }
            }
            list.add(levelSum / levelSize);
        }
        return list;
    }
}

429.N叉树的层序遍历

题目链接:N叉树的层序遍历

1.解题思路

使用层序遍历,用队列遍历每一层,然后弹出每一个,按每层个数弹出

2.我的实现

public List<List<Integer>> levelOrder(Node root) {

        List<List<Integer>> result=new ArrayList<>();
        if (root==null){
            return result;
        }
        Queue<Node> tmpNodeQueue=new LinkedList<>();
        tmpNodeQueue.offer(root);
        while (!tmpNodeQueue.isEmpty()){
            int size=tmpNodeQueue.size();
            List<Integer> tmpList=new ArrayList<>();
            Node tmpNode=new Node();
            for (int i = 0; i < size; i++) {
                tmpNode=tmpNodeQueue.poll();
                tmpList.add(tmpNode.val);
                //遍历每个节点的孩子节点
                //遇到null就停
                for (Node x:
                     tmpNode.children) {
                    tmpNodeQueue.offer(x);
                }

                
            }
            result.add(tmpList);
        }
        return result;
    }

3.标准实现

public class N0429 {
    /**
     * 解法1:队列,迭代。
     */
    public List<List<Integer>> levelOrder(Node root) {
        List<List<Integer>> list = new ArrayList<>();
        Deque<Node> que = new LinkedList<>();

        if (root == null) {
            return list;
        }

        que.offerLast(root);
        while (!que.isEmpty()) {
            int levelSize = que.size();
            List<Integer> levelList = new ArrayList<>();

            for (int i = 0; i < levelSize; i++) {
                Node poll = que.pollFirst();

                levelList.add(poll.val);

                List<Node> children = poll.children;
                if (children == null || children.size() == 0) {
                    continue;
                }
                for (Node child : children) {
                    if (child != null) {
                        que.offerLast(child);
                    }
                }
            }
            list.add(levelList);
        }

        return list;
    }

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

题目链接:在每个树行中找最大值

1.解题思路

遍历每一行二叉树,用一个列表收集,然后返回列表中的最大值,用结果列表收集。

2.我的实现

实现遇到的问题

求列表中的最大值

Collections.max(list):这个方法返回列表 list 中的最大元素。它通过自然顺序比较元素(即按照元素的 Comparable 实现来比较),因此适用于任何实现了 Comparable 接口的类型,如 IntegerString 等。

代码

 public List<Integer> largestValues(TreeNode root) {

        List<Integer> result=new ArrayList<>();
        if (root==null){
            return result;
        }
        Queue<TreeNode> tmpTreeNodeQueue=new LinkedList<>();
        tmpTreeNodeQueue.offer(root);
        while (!tmpTreeNodeQueue.isEmpty()){
            List<Integer> tmpList=new ArrayList<>();
            int size=tmpTreeNodeQueue.size();
            TreeNode tmpTreeNode=new TreeNode();
            for (int i = 0; i < size; i++) {
                tmpTreeNode=tmpTreeNodeQueue.poll();
                tmpList.add(tmpTreeNode.val);
                if (tmpTreeNode.left!=null){
                    tmpTreeNodeQueue.offer(tmpTreeNode.left);
                }
                if (tmpTreeNode.right!=null){
                    tmpTreeNodeQueue.offer(tmpTreeNode.right);
                }
            }
            int tmpVal= Collections.max(tmpList);
            result.add(tmpVal);
        }
        return result;
    }

3.标准实现

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

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

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

1.解题思路

层序遍历每层节点,使每一个节点的next指向右边节点,当i遍历到了size-1位置,就指向null,及每行的最后一个位置。

2.我的实现

public Node connect(Node root) {

        if (root==null){
            return root;
        }
        Queue<Node> queue=new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()){
            
            int size=queue.size();
            Node tmp;
            for (int i = 0; i < size; i++) {
                tmp=queue.poll();
                if (tmp.left!=null){
                    queue.offer(tmp.left);
                }
                if (tmp.right!=null){
                    queue.offer(tmp.right);
                }
                //当不为一行最后一个时,指向右边,及queue的下一个,及tmp的下一个
                //及现在的queue的第一个
                if (i!=size-1){
                    tmp.next=queue.peek();
                }else {
                    tmp.next=null;
                }
            }
        
        }
        return root;
    }

3.标准实现

class Solution {
    public Node connect(Node root) {
	Queue<Node> tmpQueue = new LinkedList<Node>();
	if (root != null) tmpQueue.add(root);

	while (tmpQueue.size() != 0){
	    int size = tmpQueue.size();

            Node cur = tmpQueue.poll();
            if (cur.left != null) tmpQueue.add(cur.left);
            if (cur.right != null) tmpQueue.add(cur.right);

	    for (int index = 1; index < size; index++){
		Node next = tmpQueue.poll();
		if (next.left != null) tmpQueue.add(next.left);
		if (next.right != null) tmpQueue.add(next.right);

                cur.next = next;
                cur = next;
	    }
	}

        return root;
    }
}

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

实现方法与上一题一样

104.二叉树的最大深度

题目:二叉树的最大深度

1.解题思路

层序遍历,遍历完一层高度加1

2.我的实现

public int maxDepth(TreeNode root) {

        if (root==null){
            return 0;
        }
        Queue<TreeNode> queue=new LinkedList<>();
        queue.offer(root);
        int high=0;
        while (!queue.isEmpty()){
            int size=queue.size();
            TreeNode tmp;
            for (int i = 0; i < size; i++) {
                tmp=queue.poll();
                if (tmp.left!=null){
                    queue.offer(tmp.left);
                }
                if (tmp.right!=null){
                    queue.offer(tmp.right);
                }
            }
            high++;
        }
        return high;
    }

3.标准实现

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

111.二叉树的最小深度

题目链接:二叉树的最小深度

1.解题思路

遍历层节点,当其中一个节点的左右孩子都为空时,break,跳出这次循环,及跳出这行,输出highmin。

2.我的实现

实现遇到的问题

实现过程中有两层循环,而break只能退出一层循环,退出之后还要通过指示器退出第二个循环。

代码

public int minDepth(TreeNode root) {

        int mHigh=0;
        if (root==null){
            return mHigh;
        }
        int cur=0;//指示器,用来跳出第二层循环
        Queue<TreeNode> queue=new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()){
            TreeNode tmp;
            int size=queue.size();
            for (int i = 0; i < size; i++) {
                tmp=queue.poll();
                if (tmp.left==null&&tmp.right==null){
                    cur=1;
                    break;
                }
                if (tmp.left!=null){
                    queue.offer(tmp.left);
                }
                if (tmp.right!=null){
                    queue.offer(tmp.right);
                }
            }
            mHigh++;
            if (cur==1){
                break;
            }
        }
        return mHigh;
    }

3.标准实现

class Solution {
    public int minDepth(TreeNode root){
        if (root == null) {
            return 0;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int depth = 0;
        while (!queue.isEmpty()){
            int size = queue.size();
            depth++;
            TreeNode cur = null;
            for (int i = 0; i < size; i++) {
                cur = queue.poll();
                //如果当前节点的左右孩子都为空,直接返回最小深度
                if (cur.left == null && cur.right == null){
                    return depth;
                }
                if (cur.left != null) queue.offer(cur.left);
                if (cur.right != null) queue.offer(cur.right);
            }
        }
        return depth;
    }
}

区别

如果当前节点的左右孩子都为空,直接返回最小深度

  • 17
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值