二叉树题解——将有序数组转换为二叉搜索树【LeetCode】传统解法
108. 将有序数组转换为二叉搜索树
方法一:中序遍历,总是选择中间位置左边的数字作为根节点
选择中间位置左边的数字作为根节点,则根节点的下标为 mid=(left+right)/2,此处的除法为整数除法。
1.1 核心思想
- 分治法:将数组分成左右两部分,递归构建左子树和右子树。
- 高度平衡:通过选择数组的中间元素作为根节点,确保左右子树的节点数尽可能相等,从而保证树的高度平衡。
1.2 具体步骤
- 递归终止条件:如果左边界
left
大于右边界right
,说明当前子数组为空,返回None
。 - 选择根节点:
- 计算中间位置
mid = (left + right) // 2
。 - 将
nums[mid]
作为根节点的值。
- 计算中间位置
- 递归构建子树:
- 左子树的范围是
[left, mid - 1]
,递归调用helper
构建左子树。 - 右子树的范围是
[mid + 1, right]
,递归调用helper
构建右子树。
- 左子树的范围是
- 返回根节点:将构建好的根节点返回。
class TreeNode(object):def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightclass Solution(object):def sortedArrayToBST(self, nums):""":type nums: List[int]:rtype: TreeNode"""def helper(left, right):# 如果左边界大于右边界,返回空节点if left > right:return None# 总是选择中间位置左边的数字作为根节点mid = (left + right) // 2# 创建根节点root = TreeNode(nums[mid])# 递归构建左子树root.left = helper(left, mid - 1)# 递归构建右子树root.right = helper(mid + 1, right)return root# 调用递归函数,返回根节点return helper(0, len(nums) - 1)
示例 1:
输入:nums = [-10, -3, 0, 5, 9]
- 初始调用:
helper(0, 4)
。mid = (0 + 4) // 2 = 2
,根节点为0
。- 左子树范围
[0, 1]
,右子树范围[3, 4]
。
- 递归调用
helper(0, 1)
:mid = (0 + 1) // 2 = 0
,根节点为-10
。- 左子树范围
[0, -1]
(返回None
),右子树范围[1, 1]
。
- 递归调用
helper(1, 1)
:mid = (1 + 1) // 2 = 1
,根节点为-3
。- 左子树范围
[1, 0]
(返回None
),右子树范围[2, 1]
(返回None
)。
- 递归调用
helper(3, 4)
:mid = (3 + 4) // 2 = 3
,根节点为5
。- 左子树范围
[3, 2]
(返回None
),右子树范围[4, 4]
。
- 递归调用
helper(4, 4)
:mid = (4 + 4) // 2 = 4
,根节点为9
。- 左子树范围
[4, 3]
(返回None
),右子树范围[5, 4]
(返回None
)。
- 最终返回的 BST 结构如下:
0/ \-10 5\ \-3 9
方法二:中序遍历,总是选择中间位置右边的数字作为根节点
选择中间位置右边的数字作为根节点,则根节点的下标为 mid=(left+right+1)/2,此处的除法为整数除法。
方法三:中序遍历,选择任意一个中间位置数字作为根节点
选择任意一个中间位置数字作为根节点,则根节点的下标为 mid=(left+right)/2 和 mid=(left+right+1)/2 两者中随机选择一个,此处的除法为整数除法。
1.1 核心思想
- 分治法:将数组分成左右两部分,递归构建左子树和右子树。
- 随机化策略:在选择中间元素时,随机决定是选择中间位置左边的元素还是右边的元素,从而生成不同的 BST。
1.2 具体步骤
- 递归终止条件:
- 如果左边界
left
大于右边界right
,说明当前子数组为空,返回None
。
- 如果左边界
- 选择根节点:
- 计算中间位置
mid = (left + right + randint(0, 1)) // 2
。randint(0, 1)
随机返回0
或1
,从而决定mid
是偏向左边还是右边。
- 将
nums[mid]
作为根节点的值。
- 计算中间位置
- 递归构建子树:
- 左子树的范围是
[left, mid - 1]
,递归调用helper
构建左子树。 - 右子树的范围是
[mid + 1, right]
,递归调用helper
构建右子树。
- 左子树的范围是
- 返回根节点:
- 将构建好的根节点返回。
from random import randint # 导入 randint 函数class TreeNode(object):def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightclass Solution(object):def sortedArrayToBST(self, nums):""":type nums: List[int]:rtype: TreeNode"""def helper(left, right):# 如果左边界大于右边界,返回空节点if left > right:return None# 选择任意一个中间位置数字作为根节点mid = (left + right + randint(0, 1)) // 2# 创建根节点root = TreeNode(nums[mid])# 递归构建左子树root.left = helper(left, mid - 1)# 递归构建右子树root.right = helper(mid + 1, right)return root# 调用递归函数,返回根节点return helper(0, len(nums) - 1)