简介
题目 - 01: 将有序数组转化为二叉搜索树 (LeetCode 108)
题目 - 02: 二叉搜索树转换为累加树 (LeetCode 538)
题目 01 - 将有序数组转化为二叉搜索树
原题链接
题目描述
给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 平衡 二叉搜索树
思路
- 平衡二叉树,要求左右子树的高度不超过
1 - 每次以数组中间值作为该层的根节点值,即下标为
mid = (l + r) / 2;- 其中
[mid + 1, r]作为右子树内节点的值,[l, mid - 1]作为左子树内节点可选值。 - 其中左子树内节点个数为
|mid - 1 - l|; 右子节点数目为r - (mid + 1)
- 其中
- 由于
mid为中间值,左右子树节点数目差为|r - 2 * mid + l)| = 0因此左右子树可以为平衡树 - 之后递归分割左区间
[l, mid - 1]和右区间[mid, r]完成左右子树的构造 - 递归返回条件,当前区间内
left > right的时候;返回空
代码实现
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
if(nums.length == 0) {
return null;
}
return bst(nums, 0, nums.length - 1);
}
public TreeNode bst(int[] nums, int l, int r) {
if(l > r) { // 区间不合法, 构造叶子节点
return null;
}
int mid = (l + r) / 2; // 左闭右闭区间
TreeNode root = new TreeNode(nums[mid]); //构造本层的父节点,mid 位置作为 val
root.left = bst(nums, l, mid - 1); //构造本层的左子树, mid 位置已经作为 root
root.right = bst(nums, mid + 1, r); //构造本层的右子树
return root;
}
}
执行结果
- 时间复杂度:
O(N) - 空间复杂度:
O(N)
题目 02 - 把二叉搜索树转化为累加树
原题链接
题目描述
给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。
提醒一下,二叉搜索树满足下列约束条件:
- 节点的左子树仅包含键
小于节点键的节点。- 节点的右子树仅包含键
大于节点键的节点。 左右子树也必须是二叉搜索树。
思路
- 由于是二叉搜索树,中序遍历得到的是
从小到大的结果 - 反向中序遍历,右根左,即得到的顺序是
从大到小;即大于或者等于 node.val 的值都会先被遍历。那么可以记录这些遍历过的节点值总和为sum; - 并且每遍历完一个节点,更新累加
sum += TreeNode.val;并且更新当前节点的val为sum即大于等于该节点值之和 - 之后每遍历一个不为空的节点,累加更新
sum并且同时更新节点值;得到的即是 累加树
代码实现
class Solution {
private int sum = 0;
public TreeNode convertBST(TreeNode root) {
if(root == null) {
return null;
}
convertBST(root.right); //右
sum += root.val;
root.val = sum;
convertBST(root.left); //左
return root;
}
}
执行结果
- 时间复杂度:
O(N) - 空间复杂度:
O(N)