https://leetcode.com/problems/maximum-binary-tree-ii/
We are given the root
node of a maximum tree: a tree where every node has a value greater than any other value in its subtree.
Just as in the previous problem, the given tree was constructed from an list A
(root = Construct(A)
) recursively with the following Construct(A)
routine:
- If
A
is empty, returnnull
. - Otherwise, let
A[i]
be the largest element ofA
. Create aroot
node with valueA[i]
. - The left child of
root
will beConstruct([A[0], A[1], ..., A[i-1]])
- The right child of
root
will beConstruct([A[i+1], A[i+2], ..., A[A.length - 1]])
- Return
root
.
Note that we were not given A directly, only a root node root = Construct(A)
.
Suppose B
is a copy of A
with the value val
appended to it. It is guaranteed that B
has unique values.
Return Construct(B)
.
Example 1:
Input: root = [4,1,3,null,null,2], val = 5
Output: [5,4,null,1,3,null,null,2]
Explanation: A = [1,4,2,3], B = [1,4,2,3,5]
Example 2:
Input: root = [5,2,4,null,1], val = 3
Output: [5,2,4,null,1,null,3]
Explanation: A = [2,1,5,4], B = [2,1,5,4,3]
Example 3:
Input: root = [5,2,3,null,1], val = 4
Output: [5,2,4,null,1,3]
Explanation: A = [2,1,5,3], B = [2,1,5,3,4]
Constraints:
1 <= B.length <= 100
/**
* 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) {}
* };
*/
算法思路:
方法1:首先copy一份,然后不断尝试插入在右子树上,因为题目中红色部分说明新的值是append to it ,也就是原来的值中序遍历之后,把val放在最后,但是还要保证是MaxTree,其实就是找到位置之后,new 一个节点root,把原先的node放在root左边即可,就是root->left = node。
class Solution {
public:
TreeNode* insertIntoMaxTree(TreeNode* root, int val) {
TreeNode* newRoot = copyTree(root);
bool hasUsed = false;
return insert(newRoot, val, hasUsed);
}
private:
TreeNode* insert(TreeNode* node, const int& val, bool& hasUsed) {
if (node == nullptr) {
if (!hasUsed) return new TreeNode(val);
return nullptr;
}
if (!hasUsed && node->val < val) {
TreeNode* root = new TreeNode(val);
root->left = node;
hasUsed = true;
return root;
}
node->right = insert(node->right, val, hasUsed);
return node;
}
TreeNode* copyTree(TreeNode* node) {
if (node == nullptr) return nullptr;
TreeNode* newNode = new TreeNode(node->val);
newNode->left = copyTree(node->left);
newNode->right = copyTree(node->right);
return newNode;
}
};
方法2:copy和insert,一起进行了,使用了一个rightSubTree布尔变量进行控制,保证插入的一定是子树的右子树,也就保证是中序遍历的append to it。
class Solution {
public:
TreeNode* insertIntoMaxTree(TreeNode* root, int val) {
bool hasUsed = false;
return buildMaxTree(root, val, hasUsed, true);
}
private:
TreeNode* buildMaxTree(TreeNode* node, const int& val,
bool& hasUsed, bool rightSubTree) {
if (node == nullptr) {
if (!hasUsed && rightSubTree) {
hasUsed = true;
return new TreeNode(val);
}
return nullptr;
}
TreeNode* newNode = new TreeNode(node->val);
TreeNode* root = nullptr;
if (!hasUsed && rightSubTree && node->val < val) {
root = new TreeNode(val);
root->left = newNode;
hasUsed = true;
}
newNode->left = buildMaxTree(node->left, val, hasUsed, false);
newNode->right = buildMaxTree(node->right, val, hasUsed, rightSubTree);
return (root != nullptr ? root : newNode);
}
};
方法3:还有一种cheat做法,是直接在原来的树上进行插入然后返回,确实快了很多(0 ms)。
class Solution {
public:
TreeNode* insertIntoMaxTree(TreeNode* root, int val) {
bool hasUsed = false;
return insert(root, val, hasUsed);
}
private:
TreeNode* insert(TreeNode* node, const int& val, bool& hasUsed) {
if (node == nullptr) {
if (!hasUsed) return new TreeNode(val);
return nullptr;
}
if (!hasUsed && node->val < val) {
TreeNode* root = new TreeNode(val);
root->left = node;
hasUsed = true;
return root;
}
node->right = insert(node->right, val, hasUsed);
return node;
}
};