LeetCode 记录-最大二叉树 II
我的解法
思路
首先,看到题目给了创建该最大二叉树的伪代码函数Construct,我想到可以根据Construct的思路写出从最大二叉树转回原来的数组的函数reverseConstruct。
所以我的总体思路就是:
- 将给的二叉树通过
reverseConstruct函数转回原本的数组a,在a的基础上生成b=[...a, val] - 通过
Constrct将b转化为最大二叉树,然后返回
代码
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {number} val
* @return {TreeNode}
*/
var insertIntoMaxTree = function (root, val) {
const originArr = reverseConstruct(root);
return construct([...originArr, val]);
};

const reverseConstruct = (root) => {
if (!root) {
return [];
}
let res = [];
if (root.left) {
res.push(...reverseConstruct(root.left));
}
res.push(root.val);
if (root.right) {
res.push(...reverseConstruct(root.right));
}
return res;
};
const construct = (arr) => {
if (!arr || arr.length === 0) {
return null;
}
const maxNum = Math.max(...arr);
const idx = arr.indexOf(maxNum);
const root = new TreeNode(maxNum);
const leftArr = arr.slice(0, idx);
const rightArr = arr.slice(idx + 1, arr.length);
if (leftArr.length) {
root.left = construct(leftArr);
}
if (rightArr.length) {
root.right = construct(rightArr);
}
return root;
};
function TreeNode(val, left, right) {
this.val = val === undefined ? 0 : val;
this.left = left === undefined ? null : left;
this.right = right === undefined ? null : right;
}
复杂度分析(自我分析,不一定对)
时间复杂度
考虑到不论是Construct还是reverseConstruct,最坏情况下就是数组中所有元素按升序或者降序排列,这种情况下,就等于是遍历,时间复杂度为O(N),N为数组中或者二叉树节点的个数。
空间复杂度
考虑递归调用栈的深度,最坏情况和时间复杂度一致,所以我觉得空间复杂度也是O(N)。
官方解法
思路
如果根节点的值小于给定的整数 val,那么新的树会以 val 作为根节点,并将原来的树作为新的根节点的左子树。
否则,我们从根节点开始不断地向右子节点进行遍历。这是因为,当遍历到的节点的值大于 val 时,由于 val 是新添加的位于数组末尾的元素,那么在构造的结果中, val 一定出现在该节点的右子树中。
当我们遍历到节点 cur 以及它的父节点 parent,并且 cur 节点的值小于 val 时,我们就可以停止遍历,构造一个新的节点,以 val 为值且以 cur 为左子树。我们将该节点作为 parent 的新的右节点,并返回根节点作为答案即可。
如果遍历完成之后,仍然没有找到比 val 值小的节点,那么我们构造一个新的节点,以 val 为值,将该节点作为 parent 的右节点,并返回根节点作为答案即可。
代码
var insertIntoMaxTree = function (root, val) {
let parent = null;
let cur = root;
while (cur) {
if (val > cur.val) {
if (!parent) {
return new TreeNode(val, root, null);
}
let node = new TreeNode(val, cur, null);
parent.right = node;
return root;
} else {
parent = cur;
cur = cur.right;
}
}
parent.right = new TreeNode(val);
return root;
};
复杂度分析
时间复杂度
O(n),其中 n 是给定的树中的节点个数,在最坏情况下,数呈现链状结构,前n-1个节点有唯一的右子节点,并且val比树中任一节点的值都要小,此时需要遍历完整棵树,时间复杂度为O(n)。
空间复杂度
O(1), 整个过程中创建的变量(额外空间)并没有随着while的递归而增加,所以空间复杂度是O(1)