day20 | 二叉树6

0.引言

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

654. 最大二叉树

Category Difficulty Likes Dislikes
algorithms Medium (82.81%) 648 -

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

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

返回 nums 构建的 ****最大二叉树 **。

示例 1:

image.png
输入:nums = [3,2,1,6,0,5]
输出:[6,3,5,null,2,0,null,null,1]
解释:递归调用如下所示:
- [3,2,1,6,0,5] 中的最大值是 6 ,左边部分是 [3,2,1] ,右边部分是 [0,5] 。
    - [3,2,1] 中的最大值是 3 ,左边部分是 [] ,右边部分是 [2,1] 。
        - 空数组,无子节点。
        - [2,1] 中的最大值是 2 ,左边部分是 [] ,右边部分是 [1] 。
            - 空数组,无子节点。
            - 只有一个元素,所以子节点是一个值为 1 的节点。
    - [0,5] 中的最大值是 5 ,左边部分是 [0] ,右边部分是 [] 。
        - 只有一个元素,所以子节点是一个值为 0 的节点。
        - 空数组,无子节点。

示例 2:

image.png
输入:nums = [3,2,1]
输出:[3,null,2,null,1]

提示:

  • 1 <= nums.length <= 1000
  • 0 <= nums[i] <= 1000
  • nums 中的所有整数 互不相同

Discussion | Solution

递归法

/*
 * @lc app=leetcode.cn id=654 lang=cpp
 *
 * [654] 最大二叉树
 */

// @lc code=start
/**
 * Definition for a binary tree node.
 * 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) {}
 * };
 */
class Solution {
 public:
  TreeNode* constructMaximumBinaryTree(vector<int>& nums) { return dfs(nums); }

 private:
  // 同样是先分,然后再创建节点,递归的时候进行连接
  TreeNode* dfs(std::vector<int> nums) {
    if (nums.empty()) {
      return nullptr;
    }
    int max_ele_idx = GetMaxElementIdx(nums);
    if (max_ele_idx == -1) return nullptr;

    TreeNode* node = new TreeNode(nums[max_ele_idx]);
    std::vector<int> nums_left(nums.begin(), nums.begin() + max_ele_idx);
    std::vector<int> nums_right(nums.begin() + max_ele_idx + 1, nums.end());

    node->left = dfs(nums_left);
    node->right = dfs(nums_right);
    return node;
  }

  int GetMaxElementIdx(std::vector<int>& nums) {
    int max_element_idx = -1, max_element = std::numeric_limits<int>::min();
    for (int i = 0; i < nums.size(); ++i) {
      if (nums[i] > max_element) {
        max_element = nums[i];
        max_element_idx = i;
      }
    }
    return max_element_idx;
  }
};
// @lc code=end

617.合并二叉树

Category Difficulty Likes Dislikes
algorithms Easy (79.16%) 1186 -

给你两棵二叉树: root1root2

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。

返回合并后的二叉树。

注意: 合并过程必须从两个树的根节点开始。

示例 1:

image.png
输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出:[3,4,5,5,4,null,7]

示例 2:

输入:root1 = [1], root2 = [1,2]
输出:[2,2]

提示:

  • 两棵树中的节点数目在范围 [0, 2000]
  • -10<sup>4</sup> <= Node.val <= 10<sup>4</sup>

Discussion | Solution

递归法

class Solution {
 public:
  TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
    if (root1 == nullptr) return root2;
    if (root2 == nullptr) return root1;

    // 返回 root1 这棵树
    root1->val += root2->val;                         
    root1->left = mergeTrees(root1->left, root2->left); 
    root1->right = mergeTrees(root1->right, root2->right); 
    return root1;
  }
};

700.二叉搜索树中的搜索

Category Difficulty Likes Dislikes
algorithms Easy (77.70%) 375 -

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

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

示例 1:

image.png
输入:root = [4,2,7,1,3], val = 2
输出:[2,1,3]

示例 2:

image.png
输入:root = [4,2,7,1,3], val = 5
输出:[]

提示:

  • 数中节点数在 [1, 5000] 范围内
  • 1 <= Node.val <= 10<sup>7</sup>
  • root 是二叉搜索树
  • 1 <= val <= 10<sup>7</sup>

Discussion | Solution

递归法

/*
 * @lc app=leetcode.cn id=700 lang=cpp
 *
 * [700] 二叉搜索树中的搜索
 */

// @lc code=start
/**
 * Definition for a binary tree node.
 * 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) {}
 * };
 */
class Solution {
 public:
  TreeNode* searchBST(TreeNode* root, int val) {
    TreeNode* res = nullptr;
    dfs(root, res, val);
    return res;
  }

 private:
  void dfs(TreeNode* node, TreeNode*& target, int& val) {
    if (node == nullptr) return;
    if (node->val == val) {
      target = node;
      return;
    }
    if (val < node->val) {
      dfs(node->left, target, val);
    } else {
      dfs(node->right, target, val);
    }
  }
};
// @lc code=end

98.# 验证二叉搜索树

Category Difficulty Likes Dislikes
algorithms Medium (36.80%) 1939 -

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左子树只包含** 小于 **当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

image.png
输入:root = [2,1,3]
输出:true

示例 2:

image.png
输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。

提示:

  • 树中节点数目范围在[1, 10<sup>4</sup>]
  • -2<sup>31</sup> <= Node.val <= 2<sup>31</sup> - 1

Discussion | Solution

迭代法

只有两个node的case过不了:

/*
 * @lc app=leetcode.cn id=98 lang=cpp
 *
 * [98] 验证二叉搜索树
 */

// @lc code=start
/**
 * Definition for a binary tree node.
 * 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) {}
 * };
 */
class Solution {
 public:
  bool isValidBST(TreeNode* root) { return dfs(root); }

 private:
  bool dfs(TreeNode* node) {
    if (node->left == nullptr && node->right == nullptr) {
      return true;
    }
    bool left = dfs(node->left);
    bool right = dfs(node->right);

    if (node->left && node->left->val < node->val) {
      left = true;
    } else {
      left = false;
    }
    if (node->right && node->right->val > node->val) {
      right = true;
    } else {
      right = false;
    }

    return left && right;
  }
};
// @lc code=end

这个题还有点坑哦:

/*
 * @lc app=leetcode.cn id=98 lang=cpp
 *
 * [98] 验证二叉搜索树
 */

// @lc code=start
/**
 * Definition for a binary tree node.
 * 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) {}
 * };
 */
class Solution {
 public:
  bool isValidBST(TreeNode* root) { return dfs(root, nullptr, nullptr); }

 private:
  bool dfs(TreeNode* node, TreeNode* left_node, TreeNode* right_node) {
    if (node == nullptr) {
      return true;
    }

    if (left_node != nullptr && node->val <= left_node->val) {
      return false;
    }

    if (right_node != nullptr && node->val >= right_node->val) {
      return false;
    }

    return dfs(node->left, left_node, node) &&
           dfs(node->right, node, right_node);
  }
};
// @lc code=end
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容