654 最大二叉树 medium
给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:
- 二叉树的根是数组中的最大元素。
- 左子树是通过数组中最大值左边部分构造出的最大二叉树。
- 右子树是通过数组中最大值右边部分构造出的最大二叉树。
通过给定的数组构建最大二叉树,并且输出这个树的根节点。
示例 :
这道题和此前的根据中序+后序/前序构造二叉树略有不同,而是只给出了一个序列,需要我们自己选取遍历方式
因为题目要从根结点开始构造,那么就要选用“前序遍历”,中左右的顺序,先选取根结点
使用递归法,返回值必然是结点类型,作为主函数的返回结果,而传入参数,根据此前构造二叉树的算法,应当传入此次使用到的序列的范围,以减少构造数组的占用的时间与空间
返回条件就是数组范围等于1的时候,说明只有一个结点需要入树;
每次递归的逻辑处理条件,要先找到本次传入数组中的最大值的索引值,作为中间结点和分割点序列,左区间用于构造左子树,右区间用于构造右子树
最终代码如下:
TreeNode* reversal(vector<int>& nums, int begin, int end) {
if (begin >= end) return nullptr;
int maxValueIndex = begin;
for (int i = begin + 1; i < end; i++) {
if (nums[i] > nums[maxValueIndex])
maxValueIndex = i;
}
TreeNode* root = new TreeNode(nums[maxValueIndex]);
// 左闭右开:[left, maxValueIndex)
root->left = reversal(nums, begin, maxValueIndex);
// 左闭右开:[maxValueIndex + 1, right)
root->right = reversal(nums, maxValueIndex + 1, end);
return root;
}
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
// 左闭右开
return reversal(nums, 0, nums.size());
}
617 合并二叉树 easy
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。
你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。
这道题和此前题目的不同之处就在于,这次是遍历两棵二叉树
递归法,返回值是结点类型,传入参数为两个二叉树的结点
返回条件也很简单,要判断两个结点是否为空,其中一个为空,就返回另一个,如果两个都为空,也可以返回另一个,结果是一样的。
处理逻辑就是创建一个新的结点,然后将遍历到的两个结点值相加。
以下是递归法的代码:
TreeNode* reversal(TreeNode* root1, TreeNode* root2) {
if (!root1) return root2;
if (!root2) return root1;
TreeNode* root = new TreeNode(0);
root->val = root1->val + root2->val;
root->left = reversal(root1->left, root2->left);
root->right = reversal(root1->right, root2->right);
return root;
}
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
return reversal(root1, root2);
}
这道题使用迭代法也是可以的,随想录中给出的方法是层序遍历(但我觉得正常的深度遍历也是可以的,就是会稍微麻烦些),层序遍历代码如下:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
queue<TreeNode*> que;
if (!root1) return root2;
if (!root2) return root1;
que.push(root1);
que.push(root2);
while (!que.empty()) {
TreeNode *cur1 = que.front();que.pop();
TreeNode *cur2 = que.front();que.pop();
cur1->val += cur2->val;
if (cur1->left != nullptr && cur2->left != nullptr) {
que.push(cur1->left);
que.push(cur2->left);
}
if (cur1->right != nullptr && cur2->right != nullptr) {
que.push(cur1->right);
que.push(cur2->right);
}
if (cur1->left == nullptr && cur2->left != nullptr) {
cur1->left = cur2->left;
}
if (cur1->right == nullptr && cur2->right != nullptr) {
cur1->right = cur2->right;
}
}
return root1;
}