当前位置: 首页> 科技> 名企 > 代码随想录刷题day17丨654.最大二叉树,617.合并二叉树,700.二叉搜索树中的搜索,98.验证二叉搜索树

代码随想录刷题day17丨654.最大二叉树,617.合并二叉树,700.二叉搜索树中的搜索,98.验证二叉搜索树

时间:2025/7/18 5:56:38来源:https://blog.csdn.net/m0_75195038/article/details/141728607 浏览次数:0次

代码随想录刷题day17丨654.最大二叉树,617.合并二叉树,700.二叉搜索树中的搜索,98.验证二叉搜索树

1.题目

1.1最大二叉树

  • 题目链接:654. 最大二叉树 - 力扣(LeetCode)

    在这里插入图片描述

  • 视频讲解:又是构造二叉树,又有很多坑!| LeetCode:654.最大二叉树_哔哩哔哩_bilibili

  • 文档讲解:https://programmercarl.com/0654.%E6%9C%80%E5%A4%A7%E4%BA%8C%E5%8F%89%E6%A0%91.html

  • 解题思路:递归(前序遍历)

    • 构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。
    • 确定递归函数的参数和返回值
      • 参数传入的是存放元素的数组,返回该数组构造的二叉树的头结点,返回类型是指向节点的指针。
    • 确定终止条件
      • 题目中说了输入的数组大小一定是大于等于1的,所以我们不用考虑小于1的情况,那么当递归遍历的时候,如果传入的数组大小为1,说明遍历到了叶子节点了。
      • 那么应该定义一个新的节点,并把这个数组的数值赋给新的节点,然后返回这个节点。 这表示一个数组大小是1的时候,构造了一个新的节点,并返回。
    • 确定单层递归的逻辑
      • 先要找到数组中最大的值和对应的下标, 最大的值构造根节点,下标用来下一步分割数组。
      • 最大值所在的下标左区间 构造左子树(这里要判断maxValueIndex > 0,因为要保证左区间至少有一个数值。)
      • 最大值所在的下标右区间 构造右子树(判断maxValueIndex < (nums.size() - 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 {public TreeNode constructMaximumBinaryTree(int[] nums) {if(nums.length == 1){return new TreeNode(nums[0]);}int maxValue = 0;int maxValueIndex = 0;for(int i =0;i < nums.length;i++){if(nums[i] > maxValue){maxValue = nums[i];maxValueIndex = i;} }TreeNode node = new TreeNode(maxValue);if(maxValueIndex > 0){int[] arrLeft = new int[maxValueIndex];for(int i = 0;i < maxValueIndex;i++){arrLeft[i] = nums[i];} node.left = constructMaximumBinaryTree(arrLeft);}if(maxValueIndex < nums.length -1){int[] arrRight = new int[nums.length - maxValueIndex - 1];for(int i = maxValueIndex + 1;i < nums.length;i++){arrRight[i -maxValueIndex - 1] = nums[i];}node.right = constructMaximumBinaryTree(arrRight);}return node;}
    }
    
  • 总结:

    • 构造二叉树都是 前序遍历

1.2合并二叉树

  • 题目链接:617. 合并二叉树 - 力扣(LeetCode)

    在这里插入图片描述

  • 视频讲解:一起操作两个二叉树?有点懵!| LeetCode:617.合并二叉树_哔哩哔哩_bilibili

  • 文档讲解:https://programmercarl.com/0617.%E5%90%88%E5%B9%B6%E4%BA%8C%E5%8F%89%E6%A0%91.html

  • 解题思路:递归(前序遍历)

    • 其实和遍历一个树逻辑是一样的,只不过传入两个树的节点,同时操作。
    • 确定递归函数的参数和返回值:
      • 首先要合入两个二叉树,那么参数至少是要传入两个二叉树的根节点,返回值就是合并之后二叉树的根节点。
    • 确定终止条件:
      • 因为是传入了两个树,那么就有两个树遍历的节点t1 和 t2,如果t1 == NULL 了,两个树合并就应该是 t2 了(如果t2也为NULL也无所谓,合并之后就是NULL)。
      • 反过来如果t2 == NULL,那么两个数合并就是t1(如果t1也为NULL也无所谓,合并之后就是NULL)。
    • 确定单层递归的逻辑:
      • 单层递归的逻辑就比较好写了,这里我们重复利用一下t1这个树,t1就是合并之后树的根节点(就是修改了原来树的结构)。
  • 代码:

    /*** 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 mergeTrees(TreeNode root1, TreeNode root2) {if(root1 == null){return root2;}if(root2 == null){return root1;}root1.val += root2.val;root1.left = mergeTrees(root1.left,root2.left);root1.right = mergeTrees(root1.right,root2.right);return root1;}
    }
    
  • 总结:

    • 优先掌握递归
    • 本题递归用中序和后序也都可以,换个顺序就行,前序更方便直观理解

1.3二叉搜索树中的搜索

  • 题目链接:700. 二叉搜索树中的搜索 - 力扣(LeetCode)

    在这里插入图片描述

  • 视频讲解:不愧是搜索树,这次搜索有方向了!| LeetCode:700.二叉搜索树中的搜索_哔哩哔哩_bilibili

  • 文档讲解:https://programmercarl.com/0700.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%9A%84%E6%90%9C%E7%B4%A2.html

  • 解题思路:递归法或者迭代法

    • 确定递归函数的参数和返回值
      • 递归函数的参数传入的就是根节点和要搜索的数值,返回的就是以这个搜索数值所在的节点。
    • 确定终止条件
      • 如果root为空,或者找到这个数值了,就返回root节点。
    • 确定单层递归的逻辑
      • 因为二叉搜索树的节点是有序的,所以可以有方向的去搜索。
      • 如果root->val > val,搜索左子树,如果root->val < val,就搜索右子树,最后如果都没有搜索到,就返回NULL。
  • 代码:

    /*** 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 searchBST(TreeNode root, int val) {if(root == null || root.val == val){return root;}TreeNode resNote = null;if(val < root.val){resNote = searchBST(root.left,val);}if(val > root.val){resNote = searchBST(root.right,val);}return resNote;}
    }
    
    class Solution {// 迭代,普通二叉树public TreeNode searchBST(TreeNode root, int val) {if (root == null || root.val == val) {return root;}Stack<TreeNode> stack = new Stack<>();stack.push(root);while (!stack.isEmpty()) {TreeNode pop = stack.pop();if (pop.val == val) {return pop;}if (pop.right != null) {stack.push(pop.right);}if (pop.left != null) {stack.push(pop.left);}}return null;}
    }class Solution {// 迭代,利用二叉搜索树特点,优化,可以不需要栈public TreeNode searchBST(TreeNode root, int val) {while (root != null)if (val < root.val) root = root.left;else if (val > root.val) root = root.right;else return root;return null;}
    }
    
  • 总结:

    • 递归和迭代 都可以掌握一下,因为本题比较简单

1.4验证二叉搜索树

  • 题目链接:98. 验证二叉搜索树 - 力扣(LeetCode)

    在这里插入图片描述

  • 视频讲解:你对二叉搜索树了解的还不够! | LeetCode:98.验证二叉搜索树_哔哩哔哩_bilibili

  • 文档讲解:https://programmercarl.com/0098.%E9%AA%8C%E8%AF%81%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91.html

  • 解题思路:递归(中序遍历)

    • 中序遍历看是否单调递增
    • 要知道中序遍历下,输出的二叉搜索树节点的数值是有序序列。有了这个特性,验证二叉搜索树,就相当于变成了判断一个序列是不是递增的了。
    • 用双指针思想优化递归过程做该题效果最好
  • 代码:

    /*** 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 {TreeNode pre = null; // 类的成员变量,用来保存中序遍历过程中前一个节点public boolean isValidBST(TreeNode root) {if(root == null){return true;// 空树是有效的二叉搜索树}boolean left = isValidBST(root.left);if(pre != null && pre.val >= root.val){return false;}pre = root;// 更新 pre 为当前节点boolean right = isValidBST(root.right);return left && right;// 返回左子树和右子树是否都是有效的 BST}
    }
    
  • 总结:

    • 遇到 搜索树,一定想着中序遍历,这样才能利用上特性。
    • 但本题是有陷阱的
      • 不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了
      • 我们要比较的是 左子树所有节点小于中间节点,右子树所有节点大于中间节点
关键字:代码随想录刷题day17丨654.最大二叉树,617.合并二叉树,700.二叉搜索树中的搜索,98.验证二叉搜索树

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: