力扣94、二叉树的中序遍历

思路:记住中序遍历的逻辑是先访问左子树,然后再访问根结点,最后访问右子树。递归即可。

 

力扣95:不同的二叉搜索树II

思路:递归。从1开始遍历数组[1, n],让遍历到的值作为根结点,假设遍历到的值是i,那么根结点的值就是i,其左子树各结点的取值范围为[0, i-1],右子树各结点的取值范围为[i+1, n],那么只需计算出[0, i-1]能生成的二叉排序树集合、[i+1, n]能生成的二叉排序树集合,然后从这俩集合中各随机挑出一个,分别作为左子树、右子树,和根结点组装在一起即可。也就是说,[0, n]能生成的二叉排序树集合和[0, i-1]、[i+1, n]能生成的二叉排序树集合有关,在遍历时递归就好了。

 

力扣96、不同的二叉搜索树

思路:递归。最快能想到的方法是按照95题的解法,先计算出集合,然后求长度。但是本题相对于95题来说,只需要一个数值,所以应该不用那么麻烦。而且按照95题解出来后,超时了。从1开始遍历数组[1, n],让遍历到的值作为根结点,假设遍历到的值是i,那么根结点的值就是i,根结点左边有i-1个数字,根结点右边有n-i个数字,那么当根结点值为i时,n个不同数字可构成的BST数就等于i-1个不同数字可构成的BST数与n-i个数字可构成的BST数之积,在遍历的过程中累加这个值。举个例子,假设n=5,假设结果是f(5),那么f(5) = f(0)×f(4) + f(1)×f(3) + f(2)×f(2) + f(3)×f(1) + f(4)×f(0),而f(4)又等于f(0)×f(3) + f(1)×f(2) + f(2)×f(1) + f(3)×f(0),f(3)又等于f(0)×f(2) + f(1)×f(1) + f(2)×f(0),f(2) = f(0)×f(1) + f(1)×f(0),f(1) = 1。可以看到有大量的重复计算,我们可以把中间值存起来,就可以省掉这些重复计算。存中间值,可以用一个map,也可以用一个数组。f(0)等于多少?f(0)必须等于1,因为只有等于1时,f(0)乘以一个其他的值才等于这个其他指。等于0的话,会丢掉一部分数。

 

力扣98、验证二叉搜索树

思路:很容易想到递归去看左子树和右子树是否是BST,但是左子树所有结点的值小于根结点,这个怎么写?

定义一个方法helper(TreeNode root, int low, int high),返回值是boolean类型,表示以root结点为根结点的树的所有结点的值是否都在(low, high)区间。判断逻辑是,先判断root.val是否在(low, high)区间,如果在,则继续判断以root.left结点为根结点的树的所有结点的值是否都在(low, root.val)区间,如果在,则继续判断以root.right结点为根结点的树的所有结点的值是否都在(root.val, high)区间。

 

力扣99、恢复二叉搜索树

思路:因为对二叉搜索树进行中序遍历,得到的集合是递增的。所以只需要在中序遍历当前的根结点得到的集合中找到两个结点,调换这两个节点的值使整个集合严格递增。所以问题就转换成了,本来有一个严格递增的集合,有人误操作调换了其中的两个元素,现在请找到这两个元素并把集合恢复成严格递增。

 

力扣100、相同的树

思路:递归。如果两个结点都为null,则返回true。如果只有一个结点为null,则返回false。剩下只剩两个结点都不为null的情况了,先比较根节点的值,再校验两个结点的左子树是否相同,然后再校验两个结点的右子树是否相同。

 

力扣101、对称二叉树

思路:第一感觉是用层序遍历,判断每一层是否对称。也可以用递归,定义一个方法,比较两个子树的值是否相等。具体逻辑是,先判断两个子树的根节点的值是否相等,如果相等,则判断第一个子树的左子树和第二个子树的右子树是否相等,以及第一个子树的右子树和第二个子树的左子树是否相等。。。如此递归下去

 

力扣102、二叉树的层序遍历

思路:用队列存储每一层的结点,略。

 

力扣103、二叉树的锯齿形层序遍历

思路:先按普通层序遍历写,打印出每一层的结点值集合,然后根据想要的结果去调整结点值集合的数据的插入顺序。

 

力扣104、二叉树的最大深度

思路:递归。一个二叉树的最大深度等于其左子树的最大深度与其右子树的最大深度的较大值加1。

 

力扣105、从前序与中序遍历序列构造二叉树

思路:

 

力扣110、平衡二叉树 这道题虽然归类是简单,但也没那么简单