【LeetCode-面试经典150题-day17】

目录

173.二叉搜索树迭代器

222.完全二叉树的节点个数

199.二叉树的右视图

637.二叉树的层平均值

 102.二叉树的层序遍历

 103.二叉树的锯齿形层次遍历


 

173.二叉搜索树迭代器

题意:

实现一个二叉搜索树迭代器类BSTIterator ,表示一个按中序遍历二叉搜索树(BST)的迭代器:

  • BSTIterator(TreeNode root) 初始化 BSTIterator 类的一个对象。BST 的根节点 root 会作为构造函数的一部分给出。指针应初始化为一个不存在于 BST 中的数字,且该数字小于 BST 中的任何元素。
  • boolean hasNext() 如果向指针右侧遍历存在数字,则返回 true ;否则返回 false 。
  • int next()将指针向右移动,然后返回指针处的数字。

注意,指针初始化为一个不存在于 BST 中的数字,所以对 next() 的首次调用将返回 BST 中的最小元素。

你可以假设 next() 调用总是有效的,也就是说,当调用 next() 时,BST 的中序遍历中至少存在一个下一个数字。

【输入样例】

["BSTIterator", "next", "next", "hasNext", "next", "hasNext", "next", "hasNext", "next", "hasNext"] [[[7, 3, 15, null, null, 9, 20]], [], [], [], [], [], [], [], [], []]

【输出样例】

[null, 3, 7, true, 9, true, 15, true, 20, false]

解题思路:

对树进行中序遍历,存储节点信息在数组中,查询操作直接在数组中进行。

 class BSTIterator{
     private int idx;
     private List<Integer> arr;
     public BSTIterator(TreeNode root){
         idx = 0;
         arr = new ArrayList<Integer>();
         inOrder(root,arr);
     }

     public int next(){
        return arr.get(idx++);
     }

     public boolean hasNext(){
         return idx < arr.size();
     }

     private void inOrder(TreeNode node, List<Integer> arr){
         if(node == null){
             return;
         }
         inOrder(node.left,arr);
         arr.add(node.val);
         inOrder(node.right,arr);
     }
 }

 /**
* 解法二,用栈,实时维护
class BSTIterator {
    private TreeNode cur;
    private Deque<TreeNode> stack;
    public BSTIterator(TreeNode root) {
        cur = root;
        stack = new LinkedList<TreeNode>();
    }
    
    public int next() {
        while(cur != null){
            stack.push(cur);
            cur = cur.left;
        }
        cur = stack.pop();
        int ret = cur.val;
        cur = cur.right;
        return ret;
    }
    
    public boolean hasNext() {
        return cur != null || !stack.isEmpty();
    }
}
 */

时间: 击败了43.62%

内存: 击败了83.64%

222.完全二叉树的节点个数

题意:

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

进阶:遍历树来统计节点是一种时间复杂度为 O(n) 的简单解决方案。你可以设计一个更快的算法吗

【输入样例】root=[1,2,3,4,5,6]

【输出样例】6

解题思路:

根据二叉树的特点,我们可以先判断,从根节点出发,左子树最左分支遍历的深度是否等于右子树最右分支遍历的深度,如果相等,是一颗满二叉树,很好计算;

如果不等,意味着这不是满二叉树,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照满二叉树情况来计算。

class Solution {
    public int countNodes(TreeNode root) {
        //满二叉树 2^高度 -1.(根节点的高度为0)
        if(root == null) return 0;
        TreeNode left = root.left;
        TreeNode right = root.right;
        int leftDepth =0,rightDepth = 0;
        while(left != null){
            left = left.left;
            ++leftDepth;
        }
        while(right != null){
            right = right.right;
            ++rightDepth;
        }
        if(rightDepth == leftDepth){
            return (2 << leftDepth) - 1;
        }
        //根节点记得要加上
        return countNodes(root.left) + countNodes(root.right) + 1;

    }
}

时间: 击败了100.00%

内存: 击败了13.81%

199.二叉树的右视图

题意:

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

【输入样例】[1,2,3,null,5,null,4]

【输出样例】[1,3,4]

解题思路:

层次遍历,并且记录每一层的深度是多少,利用map存储第depth层的节点值,因为是从左到右进行层次遍历,所以map中key=depth时的value一定是这一层的最右节点。

class Solution {
    public List<Integer> rightSideView(TreeNode root) {
       Map<Integer,Integer> map = new HashMap<Integer,Integer>();
       int max_depth = -1;
       Queue<TreeNode> nodeQueue = new LinkedList<TreeNode>();
       Queue<Integer> depthQueue = new LinkedList<Integer>();
       nodeQueue.add(root);
       depthQueue.add(0);//一个存节点信息,一个第几个节点

       while(!nodeQueue.isEmpty()){
           TreeNode node = nodeQueue.remove();
           int depth = depthQueue.remove();
           if(node != null){
               max_depth = Math.max(max_depth,depth);
               map.put(depth,node.val);//第depth层的最右侧节点

               nodeQueue.add(node.left);
               nodeQueue.add(node.right);
               depthQueue.add(depth+1);
               depthQueue.add(depth+1);

           }
       }
       List<Integer> right = new ArrayList<Integer>();
       for(int depth = 0; depth <= max_depth; ++depth){
           right.add(map.get(depth));
       }
       return right;
    }
}

时间: 击败了81.37%

内存: 击败了5.58%

637.二叉树的层平均值

题意:

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

【输入样例】root = [3,9,20,null,null,15,7]

【输出样例】[3.00000,14.50000,11.00000]

解题思路:深度优先搜索,借助两个列表,统计每一层的节点数和节点值和。

class Solution {
    public List<Double> averageOfLevels(TreeNode root) {
        List<Integer> nums = new ArrayList<Integer>();
        List<Double> sums = new ArrayList<Double>();
        List<Double> avgs = new ArrayList<Double>();

        dfs(root,0,nums,sums);
        int size = nums.size();
        for(int i=0;i<size;++i){
            avgs.add(sums.get(i)/nums.get(i));
        }
        return avgs;
    }
    public void dfs(TreeNode root, int level,List<Integer> nums,List<Double> sums){
        if(root == null){
            return;
        }
        if(level < sums.size()){
            sums.set(level,sums.get(level) + root.val);
            nums.set(level,nums.get(level)+1);
        }else{
            sums.add(1.0 * root.val);
            nums.add(1);
        }
        dfs(root.left,level+1,nums,sums);
        dfs(root.right,level+1,nums,sums);
    }
}

时间: 击败了100.00%

内存: 击败了82.36%

 102.二叉树的层序遍历

题意:

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

【输入样例】root = [3,9,20,null,null,15,7]

【输出样例】[[3],[9,20],[15,7]]

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        if(root == null) return res;

        Queue<TreeNode> que = new LinkedList<TreeNode>();//存储节点
        que.add(root);
        while(!que.isEmpty()){
            List<Integer> temp = new ArrayList<Integer>();//存储每一层的节点
            int depthSize = que.size();//当前层有多少个节点
            for(int i=1;i<=depthSize;++i){
                TreeNode node = que.poll();
                temp.add(node.val);
                if(node.left!=null){
                    que.add(node.left);
                }
                if(node.right != null){
                    que.add(node.right);
                }
            }
            res.add(temp);
        }
        return res;
    }
}

时间: 击败了91.04%

内存: 击败了27.87%

 103.二叉树的锯齿形层次遍历

题意:

给你二叉树的根节点 root ,返回其节点值的 锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。

【输入样例】root = [3,9,20,null,null,15,7]

【输出样例】[[3],[20,9],[15,7]]

解题思路:在102题的基础上,添加一个变量,判断是从左到右还是从右到左,利用queue存在的addLast和addFirst实现不同情况下元素的添加顺序。

class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        if(root == null) return res;
        Queue<TreeNode> que = new LinkedList<TreeNode>();//存储节点
        que.add(root);
        boolean leftToRight = true;
        while(!que.isEmpty()){
            Deque<Integer> temp = new LinkedList<Integer>();//存储每一层的节点
            int depthSize = que.size();//当前层有多少个节点
            for(int i=1;i<=depthSize;++i){
                TreeNode node = que.poll();
                if(leftToRight){
                    temp.addLast(node.val);
                }else{
                    temp.addFirst(node.val);
                }

                if(node.left!=null){
                    que.add(node.left);
                }
                if(node.right != null){
                    que.add(node.right);
                }
            }

            res.add(new LinkedList<Integer>(temp));
            leftToRight = !leftToRight;
        }
        return res;
    }
}

时间: 击败了72.75%

内存: 击败了26.27%

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值