Leetcode 108:将有序数组转换为二叉搜索树
题目描述
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定有序数组: [-10,-3,0,5,9],
一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:
0
/ \
-3 9
/ /
-10 5
解法1:创建辅助函数迭代
辅助函数输入有三个,分别是nums, left和right。left和right分别表示左边界和右边界。
class Solution {
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
return helper(nums, 0 , (int)nums.size() - 1);
}
TreeNode* helper(vector<int>& nums, int left, int right) {
if (left > right) return NULL;
int mid = left + (right - left) / 2; // 或left+(right-left+1)/2,区别是取的中点是偏左还是偏右的问题,两种取法得到的结果不同,但均满足题目要求
TreeNode *cur = new TreeNode(nums[mid]);
cur->left = helper(nums, left, mid - 1);
cur->right = helper(nums, mid + 1, right);
return cur;
}
};
思考:为什么函数参数nums要用引用的形式?
因为递归的过程中没有对nums这个容器的修改,我就觉得nums不用引用,然后我提交解答试了一下,发现确实能执行通过,但是执行用时大大大地增加了。我的想法是可能对于递归函数,输入参数引用相当于把参数定为全局变量,这样每次递归调用,函数就不用一次次地读取nums了,这样大大降低了执行用时。当然我的猜想不一定对,要是有大佬知道是咋回事的话欢迎评论,带带小弟~
解法2:原函数迭代
- nums.end()返回的迭代器指向最后一个元素的下一个,不存在,若v为空,begin和end返回的相同
- 本例创建的新vector的end是最后一个元素的下一个
- 本例取中点值取的是偏右的,这样的取法要规避这样一个问题,由于找中点要确立起点和终点,如果中点就是右边界点,在找下一个关于中点和右边界点的新中点时,起点会跑到终点之后
- 但是因为迭代器end返回的是最后一个元素的下一个,所以取中点值偏右,找右新中点恰好begin和end返回值相同,使得nums为empty
class Solution {
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
if(nums.empty()) return NULL;
int mid = nums.size()/2;
TreeNode* cur = new TreeNode(nums[mid]);
vector<int> nums_left(nums.begin(), nums.begin() + mid);
vector<int> nums_right(nums.begin() + mid + 1, nums.end());
cur->left = sortedArrayToBST(nums_left);
cur->right = sortedArrayToBST(nums_right);
return cur;
}
};