代码随想录算法训练营Day15|二叉树part03

116 阅读5分钟

LeetCode 110 平衡二叉树

题目链接:leetcode.cn/problems/ba…

文档讲解:programmercarl.com/0110.平衡二叉树.…

视频讲解:www.bilibili.com/video/BV1Ug…

思路

平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 我们可以遍历每个节点,获取其每个子树的高度,就可以得到当前树是否为平衡二叉树,且当前树的高度就是左右子树高度的最大值+1 故可以设计一个递归函数,获得树的高度:

  1. 递归函数的参数和返回值
    1. 全局变量:flag标识是否找到非平衡二叉树的节点
    2. 参数:根节点
    3. 返回值:树的高度
  2. 递归函数的结束条件 根节点为空,返回0
  3. 单层递归逻辑
    1. 对节点的左右子节点分别递归调用,得到子树高度
    2. 计算当前树是否为平衡二叉树
      1. 如果是平衡二叉树,返回当前树的高度
      2. 如果不是,把flag置false,返回当前树的高度 主函数中要调用递归函数,返回flag

解法

class Solution {	
	boolean flag = true;	
	public boolean isBalanced(TreeNode root) {	
		height(root);		
		return flag;	
	}
	
	public int height(TreeNode root) {		
		if (root == null) {		
			return 0;		
		}		
		int height1 = height(root.left);		
		int height2 = height(root.right);		
		if (Math.abs(height2 - height1) > 1) {		
			flag = false;		
		}		
		return Math.max(height1, height2)+1;		
	}
}

LeetCode 257 二叉树的所有路径

题目链接:leetcode.cn/problems/bi…

文档讲解:programmercarl.com/0257.二叉树的所有…

视频讲解:www.bilibili.com/video/BV1ZG…

思路

路径是所有从根节点到叶子节点的路径。我们可以前序遍历节点,在不断递归的过程中构建出路径。但从一个路径到另一个路径需要回溯,所以在递归函数返回前,要对路径进行还原 考虑递归三要素:

  1. 递归函数的参数和返回值:
    1. 全局变量:结果集合result
    2. 参数:根节点root,当前路径path
    3. 返回值:空
  2. 递归函数的结束条件: 当节点为空,直接返回
  3. 单层递归逻辑:
    1. 把节点的值放进path里
    2. 如果节点是叶子节点,把path放入结果集
    3. 如果节点不是叶子,对左右子节点递归调用
    4. 还原path,返回

解法

class Solution {
	List<String> result;	
	public List<String> binaryTreePaths(TreeNode root) {	
		result = new ArrayList<>();		
		List<String> path = new ArrayList<>();		
		traverse(root, path);		
		return result;	
	}	
	  	
	public void traverse(TreeNode root, List<String> path) {	
		if (root == null) {		
			return ;		
		}		
		path.add(String.valueOf(root.val));		
		if (root.left == null && root.right == null) {		
			result.add(String.join("->", path));		
		}		
		else {		
			traverse(root.left, path);			
			traverse(root.right, path);		
		}		
		path.remove(path.size()-1);	
	}
}

LeetCode 404 左叶子之和

题目链接:leetcode.cn/problems/su…

文档讲解:programmercarl.com/0404.左叶子之和.…

视频讲解:www.bilibili.com/video/BV1GY…

思路

一个叶子是否是左叶子,要处于其父母节点才能判断。 所以递归遍历所有可能有左叶子节点的点,把左叶子的值加到全局变量上

考虑递归三要素:

  1. 递归函数的参数和返回值
    1. 全局变量:所有的左叶子之和sum
    2. 参数:根节点root
    3. 返回值:空
  2. 递归函数的结束条件: 当节点为空,返回
  3. 单层递归逻辑
    1. 如果节点有左叶子,把左叶子的值加到sum中.左叶子下不会再有左叶子,所以只要对右子节点递归
    2. 如果节点没有左叶子,对左右子节点递归调用

解法

class Solution {
	int sum;	
	public int sumOfLeftLeaves(TreeNode root) {	
		sum = 0;		
		traverse(root);		
		return sum;	
	}	
	  	
	public void traverse(TreeNode root) {	
		if (root == null) {		
			return ;		
		}
		
		if (root.left != null && root.left.left == null && root.left.right == null) {		
			sum += root.left.val;			
			traverse(root.right);		
		}		
		else {		
			traverse(root.left);			
			traverse(root.right);		
		}	
	}
}

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

题目链接:leetcode.cn/problems/co…

文档讲解:programmercarl.com/0222.完全二叉树的…

视频讲解:www.bilibili.com/video/BV1eW…

思路

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

经过观察可以发现,完全二叉树每个叶子节点都存在于一个满二叉树中。而满二叉树的节点数量可以通过公式2h12^h-1计算。所以我们在递归到一个满二叉树时,可以直接计算节点个数,不用再往下递归。

那么如何判断完全二叉树中的一个子树是否是满二叉树呢? 从根节点开始,一直向左递归和一直向右递归如果深度一样,那么它就是满二叉树。 从整体来看,方便计算的满二叉树节点个数在底层,所以可以在回溯时把非满二叉树的根节点加在节点个数中。

考虑递归三要素:

  1. 递归函数的参数和返回值
    1. 参数:根节点
    2. 返回值:树的节点个数
  2. 递归函数的结束条件
    1. 当前节点为空,返回0
    2. 当前树为满二叉树,计算出节点个数直接返回
  3. 单层递归的逻辑
    1. 递归对左右子节点调用,得到左右子树的节点个数leftCount,rightCount
    2. 返回leftCount+rightCount+1

解法

class Solution {
	public int countNodes(TreeNode root) {	
		if (root == null) 		
			return 0;		
		}		
		TreeNode leftNode = root.left;		
		TreeNode rightNode = root.right;		
		int leftDepth = 1;		
		int rightDepth = 1;		
		while (leftNode != null) {		
			leftNode = leftNode.left;			
			leftDepth++;			
		}		
		while (rightNode != null) {		
			rightNode = rightNode.right;			
			rightDepth++;		
		}		
		if (leftDepth == rightDepth) {		
			return (int)Math.pow(2, rightDepth)-1;		
		}
		
		int leftCount = countNodes(root.left);		
		int rightCount = countNodes(root.right);		
		return leftCount+rightCount+1;	
	}
}

今日收获总结

今日学习2.5小时,二叉树的很多题目用递归方法解决还是很方便的~