day 20 第六章 二叉树 part06

总结

二叉搜索树本质是上有序数组,关键就在于有序

● 654.最大二叉树
● 617.合并二叉树
● 700.二叉搜索树中的搜索
● 98.验证二叉搜索树

● 654.最大二叉树

/*654. 最大二叉树
    中等
给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:

创建一个根节点,其值为 nums 中的最大值。
递归地在最大值 左边 的 子数组前缀上 构建左子树。
递归地在最大值 右边 的 子数组后缀上 构建右子树。
返回 nums 构建的 最大二叉树 。

 提示:
1 <= nums.length <= 1000
0 <= nums[i] <= 1000
nums 中的所有整数 互不相同
 */

class Solution_654 {
 public:
  struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  };
/*  输入参数为不重复的整数数组 nums,返回结果为根节点
      终止条件为遍历数组剩一个元素,那需要保证传入参数不为空
      单层递归逻辑:
  寻找 nums最大值作为根节点,暴力比较
      判断终止条件,若终止,返回根节点
      通过该节点切割 nums
      左子树遍历,输入为左数组,返回为左子节点
      右子树遍历,输入为右数组,返回为右子节点
      返回根节点*/
  TreeNode *build(vector<int> &nums) {
      //寻找 nums最大值作为根节点,暴力比较
      int max_val = 0;
      int max_val_index = 0;
      int temp = 0;
      for(auto i : nums){
          if(i > max_val) {
              max_val = i;
              max_val_index = temp;
          }
          temp += 1;
      }
      TreeNode *root = new TreeNode(max_val);
      //判断终止条件,若终止,返回根节点
      if(nums.size() == 1)
          return root;
      //通过该节点切割 nums
      vector<int> nums_left(nums.begin(), nums.begin() + max_val_index);
      vector<int> nums_right(nums.begin() + max_val_index + 1, nums.end());
      //左子树遍历,输入为左数组,返回为左子节点
      if (nums_left.empty())
          root->left = nullptr;
      else
          root->left = build(nums_left);
      //右子树遍历,输入为右数组,返回为右子节点
      if (nums_right.empty())
          root->right = nullptr;
      else
          root->right = build(nums_right);

      return root;

  }

  TreeNode *constructMaximumBinaryTree(vector<int> &nums) {
      if(nums.empty()){
          return nullptr;
      }
      return build(nums);
  }
};

● 617.合并二叉树


/*617. 合并二叉树
    简单
给你两棵二叉树: root1 和 root2 。
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。
 合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。
注意: 合并过程必须从两个树的根节点开始。*/

class Solution_617 {
 public:
  struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  };
/*  输入参数为俩个树的节点,返回值为新二叉树根节点
      终止条件为两个节点均为空
  单层递归逻辑:
  判断终止条件,若为真则返回
      更新新二叉树当前节点值,值为传入两节点值之和
      遍历左子树
  遍历右子树
      返回根节点

      优化方向,目前是新建了一个树,可以在原有的树上操作

      */

  TreeNode *build(TreeNode *root1, TreeNode *root2) {
      //终止条件为两个节点均为空
      if (!root1 && !root2)
          return nullptr;
      //更新新二叉树当前节点值,值为传入两节点值之和
      int val_1 = 0;
      TreeNode *root1_left = nullptr;//可能该节点本身为空,访问其左右子树会出错
      TreeNode *root1_right = nullptr;
      if (root1) {
          val_1 = root1->val;
          root1_left = root1->left;
          root1_right = root1->right;
      }

      int val_2 = 0;
      TreeNode *root2_left = nullptr;
      TreeNode *root2_right = nullptr;
      if (root2) {
          val_2 = root2->val;
          root2_left = root2->left;
          root2_right = root2->right;
      }

      TreeNode *root = new TreeNode(val_1 + val_2);
      //遍历左子树
      root->left = build(root1_left, root2_left);
      //遍历右子树
      root->right = build(root1_right, root2_right);
      return root;
  }

  TreeNode *mergeTrees(TreeNode *root1, TreeNode *root2) {
      return build(root1, root2);
  }
};

● 700.二叉搜索树中的搜索

/*700. 二叉搜索树中的搜索
    简单

给定二叉搜索树(BST)的根节点 root 和一个整数值 val。

你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。*/

class Solution_700 {
 public:
  struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  };
  /*
   * 中序遍历
输入参数为当前节点及目标值,返回值为找到的节点
终止逻辑为当前节点为空,返回空
单层递归逻辑:
判断终止条件,若为真返回空
判断当前节点值与目标值是否相等
若相等,直接返回该节点
若目标值大于当前节点值,遍历右子树
若小于,遍历左子树
返回得到的节点
   */
  TreeNode *get(TreeNode *root, int &val){
      //终止逻辑为当前节点为空,返回空
      if(!root)
          return nullptr;
      //判断当前节点值与目标值是否相等
      TreeNode *node = nullptr;
      if(val == root->val)
          return root;
      else if(val > root->val)
          node = get(root->right, val);
      else if(val < root->val)
          node = get(root->left, val);
      return node;
  }
  TreeNode *searchBST(TreeNode *root, int val) {
      return get(root, val);
  }
};

● 98.验证二叉搜索树

/*
 * 98. 验证二叉搜索树
中等
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
 */
class Solution_98 {
 public:
  struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  };
  /*
   * 输入参数为当前节点,返回值为是否为有效二叉搜索树
终止条件为当前节点为空
单层递归逻辑:
判断终止条件,返回真
遍历左子树

判断当前节点值是否大于等于上一个节点值,即是否是递增的
若为真,返回假

遍历右子树
返回真
   
   注意:应该是左子树所有节点小于中间节点,而不是左子节点小于中间节点
   */
  TreeNode* pre;
  bool get(TreeNode* node){
      //判断终止条件,返回真
      if(!node)
          return true;
      //遍历左子树
      bool left = get(node->left);
      //判断当前节点值是否大于等于上一个节点值,即是否是递增的
      if(pre && pre->val >= node->val)
          return false;
      pre = node;

      //遍历右子树
      bool right = get(node->right);

      return (left && right);
  }

  bool isValidBST(TreeNode* root) {
      return get(root);
  }
};
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 什么是二叉树? 二叉树是一种树形数据结构,其中每个节点最多有两个子节点,分别称为左子节点和右子节点。 2. 什么是二叉搜索树? 二叉搜索树是一种特殊的二叉树,其中左子节点的值小于等于父节点的值,右子节点的值大于等于父节点的值。 3. 什么是完全二叉树? 完全二叉树是一种特殊的二叉树,除了最后一层外,每一层都必须填满,且最后一层从左到右依次填入节点。 4. 什么是平衡二叉树? 平衡二叉树是一种特殊的二叉搜索树,其左右子树高度差不超过1。 5. 什么是二叉树的遍历? 二叉树的遍历是指按照某种顺序依次访问二叉树中的每个节点,常见的遍历方式包括前序遍历、中序遍历和后序遍历。 6. 什么是二叉树的前序遍历? 二叉树的前序遍历是指按照根节点、左子树、右子树的顺序依次访问二叉树中的每个节点。 7. 什么是二叉树的中序遍历? 二叉树的中序遍历是指按照左子树、根节点、右子树的顺序依次访问二叉树中的每个节点。 8. 什么是二叉树的后序遍历? 二叉树的后序遍历是指按照左子树、右子树、根节点的顺序依次访问二叉树中的每个节点。 9. 什么是二叉树的层序遍历? 二叉树的层序遍历是指按照从上到下、从左到右的顺序依次访问二叉树中的每个节点。 10. 如何判断一个二叉树是否为二叉搜索树? 可以通过中序遍历得到二叉树中所有节点的值,然后判断这些值是否按照升序排列即可判断是否为二叉搜索树。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值