「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战」
前言
每天至少一道算法题,手撕算法
题目
这是leetcode上的第108道题目108. 将有序数组转换为二叉搜索树
给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。
高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。
示例 1:
输入:nums = [-10,-3,0,5,9] 输出:[0,-3,9,-10,null,5] 解释:[0,-10,5,null,-3,null,9]
思路
第一步从题目中提取关键字
每个节点的左右两个子树的高度差的绝对值不超过 1 ,这不就是高度平衡二叉树么
我们先来了解一下什么是高度差的绝对值不超过1
先看奇数个数字的数组,我们直接上图看一下
0
/ \
-3 9
/ /
-10 5
0这个节点的左右子树的高度分别是多少呢?左子树高度为2,右子树的高度为2,所以他们的左右子树的差值为0,满足题目
我们再来看一个偶数个数字的数组
-3
/ \
-10 0
\
5
-3节点左子树的高度为1,-3节点右子树的高度为2,那么他们的高度差值是多少,是1
看上面的图,像不像把中间的数字提起来,他是以有序数组的中间元素为根节点,生成的二叉树
需要注意的是奇数和偶数之分
- 奇数的话,那么直接取中间的数字
提起来 - 偶数的话,取中间左侧的数字和取中间右侧的数字都一样,两侧的子树差值都不会大于1
才开始我们要处理边界问题,还有就是返回root节点
var sortedArrayToBST = function(nums) {
// 处理边界问题
if(!nums.length){
return null;
}
const buildBST = function(){
}
// 返回根节点
const root = buildBST();
return root;
};
现在我们就取中间的数字作为根节点的val值
var sortedArrayToBST = function(nums) {
// 处理边界问题
if(!nums.length){
return null;
}
const buildBST=function(low,high){
// 递归要写结束条件
if(low>high){
return null;
}
// 因为奇数,偶数的关系,所以center有可能是小数,那么如果是小数的话,我们选择左边的
let center = Math.floor(low+(high-low)/2);
}
const root = buildBST(0,nums.length-1);
return root;
};
然后建立node节点,并赋值左子树和右子树的根节点,方法同上,所以也肯定用递归
var sortedArrayToBST = function(nums) {
// 处理边界问题
if(!nums.length){
return null;
}
const buildBST=function(low,high){
// 递归要写结束条件
if(low>high){
return null;
}
// 因为奇数,偶数的关系,所以center有可能是小数,那么如果是小数的话,我们选择左边的
let center = Math.floor(low+(high-low)/2);
const node = new TreeNode(nums[center]);
node.left = buildBST(low,center-1);
node.right = buildBST(center+1,high);
return node;
}
const root = buildBST(0,nums.length-1);
return root;
};
题解
var sortedArrayToBST = function(nums) {
// 处理边界问题
if(!nums.length){
return null;
}
const buildBST=function(low,high){
// 递归要写结束条件
if(low>high){
return null;
}
// 因为奇数,偶数的关系,所以center有可能是小数,那么如果是小数的话,我们选择左边的
let center = Math.floor(low+(high-low)/2);
const node = new TreeNode(nums[center]);
node.left = buildBST(low,center-1);
node.right = buildBST(center+1,high);
return node;
}
const root = buildBST(0,nums.length-1);
return root;
};
- 时间复杂度:O(n),n为nums的长度,每一个数会遍历一次,所以是O(n)
- 空间复杂度:O(logn),递归就会把函数放到栈中,栈的最大深度也就是左子树或者右子树的最大深度,因为我们做的题目是平衡二叉树,高度差的绝对值不会超过1,所以栈的深度为O(logn)