LeetCode 654 最大二叉树
思路
考虑递归三要素:
- 递归函数的参数和返回值 参数:数组nums 返回值:构造出的树的根节点root
- 递归函数的结束条件 数组空,返回null
- 单层递归逻辑 遍历数组找到最大值,记录索引,创建根节点 用根节点索引切割出子数组(优化为传入原数组和起始终止索引) 递归调用返回值赋给左右子树 返回根节点
解法
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 合并二叉树
思路
本质上也是构造一个新的二叉树。 考虑递归三要素:
- 递归函数的参数和返回值 参数:根节点roo1和root2 返回值:合并的根节点root
- 递归函数的结束条件 如果两个根节点均为空,返回null 如果单个节点为空,返回非空节点
- 单层递归逻辑 根据两个根节点的值构造新节点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 二叉搜索树中的搜索
思路
二叉搜索树的使用也是一个可以递归的过程。 考虑递归三要素:
- 递归函数的参数和返回值 参数:二叉搜索树root,要搜索的值val 返回值:值为val的节点
- 递归函数的结束条件 当root为空,返回null 当root值为val,返回root
- 单层递归逻辑 如果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 验证二叉搜索树
思路
二叉搜索树的子树也是二叉搜索树,所以验证过程也可以递归 但左子树的所有节点都要小于根节点,右子树的所有节点都要大于根节点,所以需要额外的变量提供数值范围。 考虑递归三要素:
- 递归函数的参数和返回值: 参数:待验证的二叉树root,最小值min,最大值max 返回值:验证结果布尔值
- 递归函数的结束条件: 如果root为空,返回true 如果root不在范围中,返回false
- 单层递归逻辑: 对左子树递归调用,参数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,写代码还是不能偷懒,用一些小技巧或者偷懒少写几行,很容易被边界测试干掉