代码随想录算法训练营Day17|二叉树part05

84 阅读4分钟

LeetCode 654 最大二叉树

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

文档讲解:programmercarl.com/0654.最大二叉树.…

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

思路

考虑递归三要素:

  1. 递归函数的参数和返回值 参数:数组nums 返回值:构造出的树的根节点root
  2. 递归函数的结束条件 数组空,返回null
  3. 单层递归逻辑 遍历数组找到最大值,记录索引,创建根节点 用根节点索引切割出子数组(优化为传入原数组和起始终止索引) 递归调用返回值赋给左右子树 返回根节点

解法

class Solution {
	int[] nums;	
	public TreeNode constructMaximumBinaryTree(int[] nums) {	
		this.nums = nums;		
		return traverse(0, nums.length);	
	}		  
	
	public TreeNode traverse(int start, int end) {	
		if (start >= end) {		
			return null;		
		}		
		int maxIndex = -1;		
		int maxVal = Integer.MIN_VALUE;		
		for (int i = start; i < end; i++) {		
			if (nums[i] > maxVal) {			
				maxIndex = i;				
				maxVal = nums[i];			
			}		
		}		
		TreeNode root = new TreeNode(maxVal);		
		root.left = traverse(start, maxIndex);		
		root.right = traverse(maxIndex+1, end);		
		return root;	
	}
}

LeetCode 617 合并二叉树

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

文档讲解:programmercarl.com/0617.合并二叉树.…

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

思路

本质上也是构造一个新的二叉树。 考虑递归三要素:

  1. 递归函数的参数和返回值 参数:根节点roo1和root2 返回值:合并的根节点root
  2. 递归函数的结束条件 如果两个根节点均为空,返回null 如果单个节点为空,返回非空节点
  3. 单层递归逻辑 根据两个根节点的值构造新节点root 对两个根节点的左子节点递归调用,赋值给root.left 对两个根节点的右子节点递归调用,赋值给root.right 返回构造的根节点

解法

class Solution {
	public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {	
		if (root1 == null && root2 == null) {		
			return null;		
		}		
		if (root1 == null) {		
			return root2;		
		}		
		if (root2 == null) {		
			return root1;		
		}		
		TreeNode root = new TreeNode(root1.val + root2.val);		
		root.left = mergeTrees(root1.left, root2.left);		
		root.right = mergeTrees(root1.right, root2.right);		
		return root;	
	}
}

LeetCode 700 二叉搜索树中的搜索

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

文档讲解:programmercarl.com/0700.二叉搜索树中…

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

思路

二叉搜索树的使用也是一个可以递归的过程。 考虑递归三要素:

  1. 递归函数的参数和返回值 参数:二叉搜索树root,要搜索的值val 返回值:值为val的节点
  2. 递归函数的结束条件 当root为空,返回null 当root值为val,返回root
  3. 单层递归逻辑 如果root大于val,返回对左子树递归调用的结果 如果root小于val,返回对右子树递归调用的结果

解法

class Solution {
	public TreeNode searchBST(TreeNode root, int val) {	
		if (root == null || root.val == val) {		
			return root;		
		}		
		if (root.val > val) {		
			return searchBST(root.left, val);		
		}		
		else {		
			return searchBST(root.right, val);		
		}	
	}
}

LeetCode 98 验证二叉搜索树

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

文档讲解:programmercarl.com/0098.验证二叉搜索…

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

思路

二叉搜索树的子树也是二叉搜索树,所以验证过程也可以递归 但左子树的所有节点都要小于根节点,右子树的所有节点都要大于根节点,所以需要额外的变量提供数值范围。 考虑递归三要素:

  1. 递归函数的参数和返回值: 参数:待验证的二叉树root,最小值min,最大值max 返回值:验证结果布尔值
  2. 递归函数的结束条件: 如果root为空,返回true 如果root不在范围中,返回false
  3. 单层递归逻辑: 对左子树递归调用,参数max设置为root的值,min继承。 对右子树递归调用,参数min设置为root的值,max继承。 如果上述两个调用都返回true,返回true 如何表示无穷区间? 如果我们只在从根节点开始调用时传入整型的最大值和最小值,会导致边界测试不通过。所以应该用null代替,需要在地啊啊中多判断几次区间的类型再做比较。

解法

class Solution {
	public boolean isValidBST(TreeNode root) {	
		return traverse(root, null, null);	
	}	  
	
	public boolean traverse(TreeNode root, Integer min, Integer max) {	
		if (root == null) {		
			return true;		
		}		
		if (min == null && max != null) {		
			if (root.val >= max) {			
				return false;			
			}		
		}		
		if (min != null && max == null) {		
			if (root.val <= min) {			
				return false;			
			}		
		}		
		if (min != null && max != null) {		
			if (root.val >= max || root.val <= min) {			
				return false;			
			}		
		}		
		boolean flag1 = traverse(root.left, min, root.val);		
		boolean flag2 = traverse(root.right, root.val, max);		
		return flag1 && flag2;		
	}
}

今日收获总结

今日学习2h,写代码还是不能偷懒,用一些小技巧或者偷懒少写几行,很容易被边界测试干掉