Day14|算法记录 二叉树层序遍历

层序遍历

二叉树的遍历方式:

  • 深度优先遍历(递归和迭代)
    先进后出适合模拟深度优先遍历也就是递归的逻辑
  • 层序遍历
    队列先进先出,符合一层一层遍历的逻辑

Leecode

一口气刷完层序遍历十道题

102. 二叉树层序遍历

思路:
从根节点开始,将元素放入栈,然后出栈,判断出栈的元素是否存在左右的节点,存在就将元素依次放入队列(先入先出)
满老师的视频讲解比看文字更容易懂

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
            Queue<TreeNode> queue = new LinkedList<TreeNode>();

            // 需要考虑一种特殊情况
            if(root==null){
                return res;
            }
        queue.offer(root);
        int c1 =1;  // c1记录本层的节点数
        while(!queue.isEmpty()){
              List<Integer> level = new ArrayList<Integer>();
              int c2 =0; // c2记录下一层的节点数
            for(int i=0;i<c1;i++){  
                TreeNode pop = queue.poll();
                level.add(pop.val);
                if(pop.left!=null){
                    queue.offer(pop.left);
                    c2++;
                }
                if(pop.right!=null){
                    queue.offer(pop.right);
                    c2++;
                }
            }
            c1 = c2;
            res.add(level);
        }
     return res;
    }
}

上面的c1和c2其实不需要自己去赋值
c 1 c1 c1:当层元素的个数,就是开始poll出元素前队列的大小
所以就不需要 c 2 c2 c2

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
            Queue<TreeNode> queue = new LinkedList<TreeNode>();
            // 需要考虑一种特殊情况
            if(root==null){
                return res;
            }
        queue.offer(root);
        // c1记录本层的节点数
        while(!queue.isEmpty()){
              List<Integer> level = new ArrayList<Integer>();
              int c1 =queue.size(); // c2记录下一层的节点数
            for(int i=0;i<c1;i++){  
                TreeNode pop = queue.poll();
                level.add(pop.val);
                if(pop.left!=null){
                    queue.offer(pop.left);
                }
                if(pop.right!=null){
                    queue.offer(pop.right);
                }
            }
            res.add(level);
        }
     return res;
    }
}
107. 二叉树的层次遍历II

题目描述
思路一:只需要在原来的基础上,将结果反转,只需要在原本的 r e t u r n return return r e s ; res; res;前面加上反转的代码:

 //开始反转
      List<List<Integer>> reverse = new ArrayList<List<Integer>>();
     for(int i=res.size()-1;i>=0;i--){
         reverse.add(res.get(i));
     }
    return reverse;

思路二:利用链表,每一次添加的时候都向头部添加

class Solution {
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
    //***************************主要改了这一句***********//
        LinkedList<List<Integer>> res = new LinkedList<>();
   //****************************************************//
            Queue<TreeNode> queue = new LinkedList<TreeNode>();

            // 需要考虑一种特殊情况
            if(root==null){
                return res;
            }
        queue.offer(root);
        int c1 =1;  // c1记录本层的节点数
        while(!queue.isEmpty()){
              List<Integer> level = new ArrayList<Integer>();
              int c2 =0; // c2记录下一层的节点数
            for(int i=0;i<c1;i++){  
                TreeNode pop = queue.poll();
                level.add(pop.val);
                if(pop.left!=null){
                    queue.offer(pop.left);
                    c2++;
                }
                if(pop.right!=null){
                    queue.offer(pop.right);
                    c2++;
                }
            }
            c1 = c2;
            res.addFirst(level);
        }
     return res;
    }
}
199.二叉树的右视图
  • 解法:队列,迭代。
    每次返回每层的最后一个字段即可。
class Solution {
    public List<Integer> rightSideView(TreeNode root) {
       List<Integer> list = new ArrayList<>();
        Deque<TreeNode> que = new LinkedList<>();
       
        if (root == null) {
            return list;
        }

        que.offer(root);
        int c1=1;
        while (!que.isEmpty()) {
            int c2=0;
            for (int i = 0; i < c1; i++) {
                TreeNode poll = que.poll();
                if (poll.left != null) {
                    que.add(poll.left);
                    c2++;
                }
                if (poll.right != null) {
                    que.add(poll.right);
                    c2++;
                }
                if (i == c1 - 1) {
                    list.add(poll.val);
                }
            }
            c1=c2;
        }
        return list;
    }
}

637.二叉树的层平均值

 List<Double> res = new ArrayList<Double>();
Queue<TreeNode> queue = new LinkedList<TreeNode>();
......
......
 while(!queue.isEmpty()){
             double sum=0.0;
            int c2 =0; // c2记录下一层的节点数
            for(int i=0;i<c1;i++){  
                TreeNode pop = queue.poll();
                sum+=pop.val;
             ......
             ......
             res.add(sum/c1);
            c1 = c2;
        }
     return res;
             
429.N叉树的层序遍历
515. 在每个树行中找最大值
116. 填充每个节点的下一个右侧节点指针

自己写的题解

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

直接用上一题的代码

104. 二叉树的最大深度

二叉树的遍历方式:

  • 深度优先遍历(递归和迭代)
    先进后出适合模拟深度优先遍历也就是递归的逻辑
  • 层序遍历
    队列先进先出,符合一层一层遍历的逻辑

满老师的三种解法

1.深度优先遍历—递归

class Solution {
    public int maxDepth(TreeNode root) {
     if(root == null){
         return 0;
     }
    int d1 = maxDepth(root.left);
    int d2 = maxDepth(root.right);
    return Integer.max(d1,d2) + 1;
    }
}
  1. 深度优先遍历—迭代(
    后序遍历,栈中最大元素就是最大深度

  2. 层序遍历

111. 二叉树的最小深度

满老师讲过
1.递归
2.层序遍历

226. 翻转二叉树

深度优先遍历----递归:

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

层序遍历:
遍历每一个节点的时候,交换其左右两个节点

class Solution {
    public TreeNode invertTree(TreeNode root) {
   
            Queue<TreeNode> queue = new LinkedList<TreeNode>();
            // 需要考虑一种特殊情况
            if(root==null){
                return root;
            }
        queue.offer(root);
        // c1记录本层的节点数
        while(!queue.isEmpty()){
           
              int c1 =queue.size(); // c2记录下一层的节点数
            for(int i=0;i<c1;i++){  
                TreeNode pop = queue.poll();
               swap(pop);
                if(pop.left!=null){
                    queue.offer(pop.left);
                }
                if(pop.right!=null){
                    queue.offer(pop.right);
                }
            }
        }
     return root;
    }

    public void swap(TreeNode root){
        
        TreeNode t = root.left;
        root.left = root.right;
        root.right = t;
    }
}

101. 对称二叉树

满老师的讲解

 */
class Solution {
    public boolean isSymmetric(TreeNode root) {
      return check(root.left,root.right);
    }
    
    public boolean check(TreeNode left, TreeNode right){
        //都为null
        if(left==null&&right ==null){
            return true;
        }
      // 只有其中之一为null
        if(left==null||right==null){
            return false;
        }

      // 都不为null,有值
      //1.不等
      if(left.val != right.val){
        return false;
      }
      //2.相等
      //就让左节点的左边   和  右节点的右边 
      // 左节点的右边   和   右节点的左边
      return check(left.left,right.right)&&check(left.right,right.left);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值