LeetCode 669. 修剪二叉搜索树
📖 考察点
二叉搜索树的性质
📖 题意理解
给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。
所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。
💡 解题思路
🔑 关键点总结
💻 代码实现
JavaScript
// myself
var trimBST = function (root, low, high) {
if (!root) return;
if (root.val < low || root.val > high) {
// 不在范围内
if (!root.left && !root.right) {
// case1 :没有子节点
return null;
} else if (!root.left) {
// case2 :只有单个节点
return trimBST(root.right, low, high);
} else if (!root.right) {
return trimBST(root.left, low, high);
} else {
// case3 :2个子节点都存在 ->->-> 根据二叉树的性质,如果不在区间内只需要在另一侧去找符合范围的节点即可,所以不需要合并。
// 合并两个子节点
return trimBST(mergeBSTChild(root), low, high);
}
} else {
// 范围内
root.left = trimBST(root.left, low, high);
root.right = trimBST(root.right, low, high);
return root;
}
};
const mergeBSTChild = (node) => {
// 左孩子链接在右孩子最左侧 | 相反
let left = node.left;
let right = node.right;
while (right.right) {
right = right.right;
}
right.right = left;
node.left = null;
return node.right;
};
// 利用二叉搜索树的性质,省去合并操作
var trimBST = function (root, low, high) {
if (!root) {
return null;
}
if (root.val < low) {
return trimBST(root.right, low, high);
}
if (root.val > high) {
return trimBST(root.left, low, high);
}
root.left = trimBST(root.left, low, high);
root.right = trimBST(root.right, low, high);
return root;
};
⏱️ 复杂度分析
📚 总结与反思
LeetCode 108.将有序数组转换为二叉搜索树
📖 考察点
二叉搜索树 平衡二叉树
📖 题意理解
平衡二叉树 是指该树所有节点的左右子树的高度相差不超过 1
给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 平衡 二叉搜索树。
💡 解题思路
找到根节点,递归执行
思路一:
思路二:
🔑 关键点总结
💻 代码实现
JavaScript
var sortedArrayToBST = function (nums) {
if (nums.length === 0) {
return null;
}
if (nums.length === 1) {
return new TreeNode(nums[0]);
}
let index = ~~(nums.length / 2);
let cur = new TreeNode(nums[index]);
// 切数组
let leftNums = nums.slice(0, index);
let rightNums = nums.slice(index + 1);
cur.left = sortedArrayToBST(leftNums);
cur.right = sortedArrayToBST(rightNums);
return cur;
};
var sortedArrayToBST = function (nums) {
const buildTree = (Arr, left, right) => {
if (left > right) return null;
let mid = Math.floor(left + (right - left) / 2);
let root = new TreeNode(Arr[mid]);
root.left = buildTree(Arr, left, mid - 1);
root.right = buildTree(Arr, mid + 1, right);
return root;
};
return buildTree(nums, 0, nums.length - 1);
};
LeetCode 538.把二叉搜索树转换为累加树
📖 考察点
二叉搜索树 中序便历
📖 题意理解
给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。
提醒一下,二叉搜索树满足下列约束条件:
- 节点的左子树仅包含键 小于 节点键的节点。
- 节点的右子树仅包含键 大于 节点键的节点。
- 左右子树也必须是二叉搜索树。
💡 解题思路
采用反向中序便历,记录前一个节点的值,即可更改
🔑 关键点总结
💻 代码实现
JavaScript
// myself
var convertBST = function (root) {
let cur = root;
let stack = [];
if (!root) {
return null;
}
let pre = 0;
while (stack.length || cur) {
if (cur) {
stack.push(cur);
cur = cur.right;
} else {
let node = stack.pop();
node.val += pre;
pre = node.val;
cur = node.left;
}
}
return root;
};