题目描述
最大树定义:一个树,其中每个节点的值都大于其子树中的任何其他值。
给出最大树的根节点 root
。
就像 之前的问题 那样,给定的树是从表 A(root = Construct(A))
递归地使用下述 Construct(A)
例程构造的:
- 如果
A
为空,返回null
。* - 否则,令
A[i]
作为A
的最大元素。创建一个值为A[i]
的根节点root
。 root
的左子树将被构建为Construct([A[0], A[1], ..., A[i-1]])
root
的右子树将被构建为Construct([A[i+1], A[i+2], ..., A[A.length - 1]])
- 返回
root
。
请注意,我们没有直接给定 A
,只有一个根节点 root = Construct(A)
。
假设 B
是 A
的副本,并附加值 val
。保证 B
中的值是不同的。
返回 Construct(B)
。
样例
输入:root = [4,1,3,null,null,2], val = 5
输出:[5,4,null,1,3,null,null,2]
解释:A = [1,4,2,3], B = [1,4,2,3,5]
输入:root = [5,2,4,null,1], val = 3
输出:[5,2,4,null,1,null,3]
解释:A = [2,1,5,4], B = [2,1,5,4,3]
[]https://assets.leetcode.com/uploads/2019/02/21/maximum-binary-tree-3-2.png)
输入:root = [5,2,3,null,1], val = 4
输出:[5,2,4,null,1,3]
解释:A = [2,1,5,3], B = [2,1,5,3,4]
注意
1 <= B.length <= 100
算法
(递归) $O(n)$
- 首先通过递归将
A
数组反构造出来,反构造的过程同样需要递归,每一层首先反构造左半部分,然后将当前的值放进数组中,然后递归反构造右半部分。 - 在末尾添加新数字后,进行构造操作,按照题目说的流程递归即可。
时间复杂度
- 反构造和构造过程都是线性的,故时间复杂度为 $O(n)$。
空间复杂度
- 需要额外的数组记录反构造的结果和系统栈空间,故空间复杂度为 $O(n)$。
C++ 代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void deconstruct(TreeNode *rt, vector<int> &A) {
if (rt == nullptr)
return;
deconstruct(rt -> left, A);
A.push_back(rt -> val);
deconstruct(rt -> right, A);
}
TreeNode *construct(const vector<int> &A, int l, int r) {
if (l == r)
return nullptr;
int max_idx = l;
for (int i = l + 1; i < r; i++)
if (A[i] > A[max_idx])
max_idx = i;
TreeNode *rt = new TreeNode(A[max_idx]);
rt -> left = construct(A, l, max_idx);
rt -> right = construct(A, max_idx + 1, r);
return rt;
}
TreeNode* insertIntoMaxTree(TreeNode* root, int val) {
vector<int> A;
deconstruct(root, A);
A.push_back(val);
int l = 0, r = A.size();
return construct(A, l, r);
}
};