题解 | #判断一棵二叉树是否为搜索二叉树和完全二叉树#

判断一棵二叉树是否为搜索二叉树和完全二叉树

http://www.nowcoder.com/practice/f31fc6d3caf24e7f8b4deb5cd9b5fa97

方法一(递归+广度优先搜索)

1.题意整理

  • 给定一颗二叉树,树中没有重复节点。
  • 判断该树是否是二叉搜索树、是否是完全二叉树。

2.思路整理

判断搜索二叉树(BST): 考虑搜索二叉树的定义,每一个节点的值应该大于等于左子树中的最大值,小于等于右子树中的最小值。所以我们可以利用递归遍历每一个节点,如果某个节点不满足定义,则不合法,直接返回false。

图解展示:

alt

判断完全二叉树(CST): 完全二叉树是严格按照顺序从上到小,从左到右排列的二叉树,只有上一层满了,才可以在下一层从左到右开始排。所以可以利用层序遍历模拟这个过程,如果遍历的过程中,发现之前出现过空节点,而当前节点不是叶子节点,则不合法。

图解展示:

alt

3.代码实现

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param root TreeNode类 the root
     * @return bool布尔型一维数组
     */
    
    public boolean[] judgeIt (TreeNode root) {
        return new boolean[]{BST(root,Integer.MIN_VALUE,Integer.MAX_VALUE),CST(root)};
    }
    //判断是否为搜索二叉树,left表示当前左子树节点最大值,right表示当前右子树节点最小值
    private boolean BST(TreeNode root,long left,long right){
        //递归终止条件
        if(root==null) return true;
        //如果当前节点小于等于左子树节点最大值或者大于等于右子树节点最小值,则不合法
        if(root.val<=left||root.val>=right){
            return false;
        }
        //考虑左子树时,left不变(left可能不变,也可能变小,但是变小的情况仍然可以用原来的left校验合法性,所以left可以保持不变),对应右子树由于要考虑当前节点,right变为root.val,同理考虑右子树
        return BST(root.left,left,root.val)&&BST(root.right,root.val,right);
    }
    //判断是否为完全二叉树
    private boolean CST(TreeNode root){
        if(root==null) return true;
        //新建队列,用于层序遍历
        LinkedList<TreeNode> queue=new LinkedList<>();
        queue.offer(root);
        //判断是否走过空节点
        boolean reachNull=false;
        while(!queue.isEmpty()){
            int n=queue.size();
            for(int i=0;i<n;i++){
                //当前层节点
                TreeNode node=queue.poll();
                if(node.left!=null){
                    //如果当前左子节点不为空,并且走过空节点,则不合法
                    if(reachNull){
                        return false;
                    }
                    //左子节点入队列
                    queue.offer(node.left);
                }
                else{
                    reachNull=true;
                }
                if(node.right!=null){
                    //如果当前右子节点不为空,并且走过空节点,则不合法
                    if(reachNull){
                        return false;
                    }
                    //右子节点入队列
                    queue.offer(node.right);
                } 
                else{
                    reachNull=true;
                }
            }
        }
        return true;
    }
}

4.复杂度分析

  • 时间复杂度:两个函数都需要遍历树中所有节点,所以时间复杂度为O(n)O(n)
  • 空间复杂度:判断搜索二叉树时,最坏情况下,递归栈深度为n,判断完全二叉树时,需要借助大小为n的队列,所以空间复杂度是O(n)O(n)
xqxls的题解 文章被收录于专栏

牛客题解

全部评论

相关推荐

今天 10:56
门头沟学院 Java
点赞 评论 收藏
分享
06-27 12:54
已编辑
门头沟学院 Java
累了,讲讲我的大学经历吧,目前在家待业。我是一个二本院校软件工程专业。最开始选专业是觉得计算机感兴趣,所以选择了他。本人学习计算机是从大二暑假结束开始的,也就是大三开始。当时每天学习,我个人认为Java以及是我生活的一部分了,就这样持续学习了一年半,来到了大四上学期末,大概是在12月中旬,我终于找的到了一家上海中厂的实习,但我发现实习生的工作很枯燥,公司分配的活也不多,大多时间也是自己在自学。就这样我秋招末才找到实习。时间来到了3月中旬,公司说我可以转正,但是转正工资只有7000,不过很稳定,不加班,双休,因为要回学校参加答辩了,同时当时也是心高气傲,认为可以找到更好的,所以放弃了转正机会,回学校准备论文。准备论文期间就也没有投递简历。然后时间来到了5月中旬,这时春招基本也结束了,然后我开始投递简历,期间只是约到了几家下场面试。工资也只有6-7k,到现在我不知道该怎么办了。已经没有当初学习的心劲了,好累呀,但是又不知道该干什么去。在家就是打游戏,boss简历投一投。每天日重一次。26秋招都说是针对26届的人,25怎么办。我好绝望。要不要参加考公、考研、央国企这些的。有没有大佬可以帮帮我。为什么感觉别人找工作都是顺其自然的事情,我感觉自己每一步都在艰难追赶。八股文背了又忘背了又忘,我每次都花很长时间去理解他,可是现在感觉八股、项目都忘完了。真的已经没有力气再去学习了。图片是我的简历,有没有大哥可以指正一下,或者说我应该走哪条路,有点不想在找工作了。
码客明:太累了就休息一下兄弟,人生不会完蛋的
如果实习可以转正,你会不...
点赞 评论 收藏
分享
练习生懒羊羊:开飞机把这个公司创飞吧
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务