题目链接:
给你一个整数数组 nums
,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡
高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。
示例 1:
输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:
示例 2:
输入:nums = [1,3]
输出:[3,1]
解释:[1,3] 和 [3,1] 都是高度平衡二叉搜索树。
提示:
-
1 <= nums.length <= 104
-
-104 <= nums[i] <= 104
-
nums
按 严格递增 顺序排列
解题思路
这道题类似于
题目中说,要转换为一棵高度平衡二叉搜索树。但其实不用强调高度平衡,因为用递增的数组构造二叉搜索树时,大家默认都是取数组中间的值作为节点来构造,这样构成平衡树是自然而然的事情,反而构成不平衡的二叉搜索树是麻烦的。
所以只要递归地以 数组 的中间值构造节点,再以 中间值 为分界构造 当前节点 的左右孩子就可。
C++
class Solution { public: TreeNode* sortedArrayToBST(vector<int>& nums) { if (nums.size() == 0) return nullptr; if (nums.size() == 1) { TreeNode* node = new TreeNode(nums[nums.size() - 1]); return node; } // 找到数组的中间的一个数,它就是此时的根节点 int ri = nums.size() / 2; TreeNode* node = new TreeNode(nums[ri]); // 根据 ri 将数组分成左右两部分,然后递归构造 当前根节点 的左孩子 和右孩子 vector<int> nums1(nums.begin(), nums.begin() + ri); vector<int> nums2(nums.begin() + ri + 1, nums.end()); node->left = sortedArrayToBST(nums1); node->right = sortedArrayToBST(nums2); return node; } };
上面的方法在每次递归时都要生成两个数组,会造成额外的内存开销。所以还可以采用下面的方法
class Solution { public: TreeNode* getTree(vector<int>& nums, int left, int right) { if (left > right) return nullptr; // 这种写法防止整型溢出 int ri = left + (right - left)/2; TreeNode* node = new TreeNode(nums[ri]); node->left = getTree(nums, left, ri - 1); node->right = getTree(nums, ri + 1, right); return node; } TreeNode* sortedArrayToBST(vector<int>& nums) { TreeNode* root = getTree(nums, 0, nums.size() - 1); return root; } };
JavaScript
/** * @param {number[]} nums * @return {TreeNode} */ var sortedArrayToBST = function(nums) { if (nums.length === 0) return null; if (nums.length === 1) { let node = new TreeNode(nums[nums.length - 1]); return node; } let ri = Math.floor(nums.length / 2); let node = new TreeNode(nums[ri]); let nums1 = nums.slice(0, ri); let nums2 = nums.slice(ri + 1) node.left = sortedArrayToBST(nums1); node.right = sortedArrayToBST(nums2); return node; };
/** * @param {number[]} nums * @return {TreeNode} */ var sortedArrayToBST = function(nums) { const getTree = (nums, left, right) => { if (left > right) return null; let ri =Math.floor(left + (right - left) / 2); let node = new TreeNode(nums[ri]); node.left = getTree(nums, left, ri - 1); node.right = getTree(nums, ri + 1, right); return node; } let root = getTree(nums, 0, nums.length - 1); return root; };