作者简介:大家好,我是未央;
博客首页:未央.303
系列专栏:牛客面试必刷TOP101
每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!!!!!
前言
一、BM34 判断是不是二叉搜索树
题目描述
描述:
给定一个二叉树根节点,请你判断这棵树是不是二叉搜索树。
二叉搜索树满足每个节点的左子树上的所有节点均小于当前节点且右子树上的所有节点均大于当前节点。
举例说明:
示例1:
示例2:
题目解析
方法:二叉树递归
解题思路:
二叉搜索树的特性就是中序遍历是递增序。既然是判断是否是二叉搜索树,那我们可以使用中序递归遍历。只要之前的节点是二叉树搜索树,那么如果当前的节点小于上一个节点值那么就可以向下判断。*只不过在过程中我们要求反退出。比如一个链表1->2->3->4,只要for循环遍历如果中间有不是递增的直接返回false即可。
if(root.val < pre) return false;
解题步骤:
- step 1:首先递归到最左,初始化maxLeft与pre。
- step 2:然后往后遍历整棵树,依次连接pre与当前节点,并更新pre。
- step 3:左子树如果不是二叉搜索树返回false。
- step 4:判断当前节点是不是小于前置节点,更新前置节点。
- step 5:最后由右子树的后面节点决定。
代码编写:
import java.util.*; public class Solution { //首先,我们定义了一个全局变量pre,用于记录中序遍历中前一个节点的值。 //初始时,将pre设置为最小整数值;目的是为了让他pre的初始值一定是小于第一个节点的值的。 int pre = Integer.MIN_VALUE; //中序遍历 public boolean isValidBST (TreeNode root) { //1.首先判断根节点root是否为空。如果为空,说明当前子树为空树,我们认为是有效的二叉搜索树,返回true。 if (root == null) return true; //先进入左子树 //2.先递归调用isValidBST函数,传入左子树root.left,判断左子树是否为有效的二叉搜索树。如果返回值为false,说明左子树不满足二叉搜索树的条件,直接返回false。 if(!isValidBST(root.left)) return false; //3.然后,我们判断当前节点root的值是否小于pre。如果是,说明当前节点的值小于前一个节点的值,不满足二叉搜索树的条件,直接返回false。 if(root.val < pre) return false; //4.更新最值 //将pre更新为当前节点root的值是为了在遍历过程中记录前一个节点的值,以便后续比较当前节点的值和前一个节点的值 pre = root.val; //再进入右子树 //5.最后,我们递归调用isValidBST函数,传入右子树root.right,判断右子树是否为有效的二叉搜索树。如果返回值为false,说明右子树不满足二叉搜索树的条件,直接返回false。 return isValidBST(root.right); //6.如果以上条件都不满足,说明当前子树满足二叉搜索树的条件,返回true。 } }
二、BM35 判断是不是完全二叉树
题目描述
描述:
给定一个二叉树,确定他是否是一个完全二叉树。
完全二叉树的定义:若二叉树的深度为 h,除第 h 层外,其它各层的结点数都达到最大个数,第 h 层所有的叶子结点都连续集中在最左边,这就是完全二叉树。(第 h 层可能包含 [1~2h] 个节点)
举例说明:
示例1:
示例2:
示例3:
题目解析
方法:层次遍历(推荐使用)
思路:
对完全二叉树最重要的定义就是叶子节点只能出现在最下层和次下层,所以我们想到可以使用队列辅助进行层次遍历——从上到下遍历所有层,每层从左到右,只有次下层和最下层才有叶子节点,其他层出现叶子节点就意味着不是完全二叉树。
解题步骤:
- step 1:先判断空树一定是完全二叉树。
- step 2:初始化一个队列辅助层次遍历,将根节点加入。
- step 3:逐渐从队列中弹出元素访问节点,如果遇到某个节点为空,进行标记,代表到了完全二叉树的最下层,若是后续还有访问,则说明提前出现了叶子节点,不符合完全二叉树的性质。
- step 4:否则,继续加入左右子节点进入队列排队,等待访问。
图示说明:
代码编写: