二叉树的问题考虑使用递归来解决。
三道题套路解决递归问题 | lyl's blog (lyl0724.github.io)https://lyl0724.github.io/2020/01/25/1/
-
确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
-
确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
-
确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。
104、二叉树的最大深度
给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
求二叉树的最大深度,那么直接套递归解题三部曲模版:
- 确定终止条件: 什么情况下递归结束?如果题目只是遍历并没有其他的返回什么东西 那么终止条件只有一个 if(root==null) return xx;如果题目是要求返回东西的话,那么终止条件应该还包括只有一个根结点的时候,返回什么东西。
- 确定递归函数的参数和返回值:参数就是传入树的根节点,返回就返回这棵树的深度,所以返回值为int类型。
- 确定单层递归的逻辑:先求它的左子树的深度,再求的右子树的深度,最后取左右深度最大的数值 再+1 就是目前节点为根节点的树的深度。 首先,还是强调要走出之前的思维误区,递归后我们眼里的树一定是这个样子的,看下图。此时就三个节点:root、root.left、root.right,其中根据第二步,root.left和root.right分别记录的是root的左右子树的最大深度。()
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
if(root==null) return 0;//终止条件1
if(root.left==null&&root.right==null) return 1;//终止条件2
int left=maxDepth(root.left);//单层递归的逻辑
int right=maxDepth(root.right);//单层递归的逻辑
return Math.max(left,right)+1;
}
}
108、将有序数组转换为二叉搜索树
给你一个整数数组 nums ,其中元素已经按升序排列,请你将其转换为一棵 高度平衡 二叉搜索树。高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。
二分查找和递归一起使用。
思路:1、看到题目 (数组&&有序)→二分查找的思路
2、二叉树→递归
二分查找的递归:
- 找终止条件。 什么情况下递归结束?当然是查找的时候,查找是不断缩小left和right的范围,直到:left>right,结束递归。 如果题目只是遍历并没有其他的返回什么东西 那么终止条件只有一个 if(root==null) return xx;如果题目是要求返回东西的话,那么终止条件应该还包括只有一个根结点的时候,返回什么东西。------此题就是遍历而已
- 确定递归函数的参数和返回值:二分查找法传递的参数应该是数组,已经数组的第一个元素(left)和最后一个元素(right)。 应该返回什么?题目求的是将有序数组转成平衡二叉树,每一步的递归都是返回出一个满足平衡二叉树的结点,这一步可以结合第三步来看。
- 确定单层递归的逻辑: 将有序数组的最中间(mid)作为根结点,那么mid左边的数就是左节点、mid右边的数就是右节点。那么单层递归就是做出根的左节点、右节点。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
//在构造二叉树的时候尽量不要重新定义左右区间数组,而是用下标来操作原数组。
return binartSearch(nums,0,nums.length-1);
}
public TreeNode binartSearch(int []nums,int left,int right){
if(left>right) return null; //递归的二分查找的终止条件
int mid=left+(right-left)/2;
int midValue=nums[mid];
TreeNode root = new TreeNode(midValue);//不要忘记了要先创建root结点对象,形参没有给。
root.left=binartSearch(nums,left,mid-1);
root.right=binartSearch(nums,mid+1,right);
return root;
}
}
110、平衡二叉树
给定一个二叉树,判断它是否是高度平衡的二叉树。
平衡二叉树定义:左右节点的高度差不超过1【这句话包含了两层意思:1)、根结点的左子树和右子树的高度差不超过1。 2)、根结点的左子树的左子树和右子树的高度差不超过1且根结点的右子树的左子树有和右子树的高度差不超过1】
那么我们就可以递归去实现
1、根结点的左子树和右子树的高度差不超过1。即:递归算出树中节点的高度,再将实参改变,求出根结点的左右子树的高度差。
2、除了根结点的左子树和右子树的高度差不超过1,还要保证:根结点的左子树的左子树和右子树的高度差不超过1且根结点的右子树的左子树有和右子树的高度差不超过1。即:isBalanced(root.left)&&isBalanced(root.right) 要保证return Math.abs(left-right)<=1
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
//是否是平衡二叉树:该树的左子树和右子树高度差不超过1
public boolean isBalanced(TreeNode root) {
if(root==null) return true;//终止条件1
if(root.left==null&&root.right==null) return true;//终止条件2
int left=maxDeepth(root.left);
int right=maxDeepth(root.right);
return Math.abs(left-right)<=1&&isBalanced(root.left)&&isBalanced(root.right);
}
public int maxDeepth(TreeNode root){
if(root==null) return 0;//终止条件1
if(root.left==null&&root.right==null) return 1;//终止条件2
int left=maxDeepth(root.left);
int right=maxDeepth(root.right);
return Math.max(left,right)+1;
}
}
目前做的二叉树的题目——————递归解决