108. 将有序数组转换为二叉搜索树
问题描述:
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定有序数组: [-10,-3,0,5,9],
一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:
0
/ \
-3 9
/ /
-10 5
解题思路:
- 为了将有序数组分配均匀,从中间开始取值,慢慢向两边过度
- 使用递归法,每次选定一个节点,然后找到他的左节点和右节点。
- 一次取左右各一半,继续上面步骤
代码实现
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def sortedArrayToBST(self, nums):
if nums:
m = len(nums) // 2
r = TreeNode(nums[m])
r.left, r.right = map(self.sortedArrayToBST, [nums[:m], nums[m+1:]])
return r
110. 平衡二叉树
问题描述:
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
示例 1:
给定二叉树 [3,9,20,null,null,15,7]
3
/ \
9 20
/ \
15 7
返回 true 。
示例 2:
给定二叉树 [1,2,2,3,3,null,null,4,4]
1
/ \
2 2
/ \
3 3
/ \
4 4
返回 false 。
解题思路:
此处为题解中大牛写的解题思路,讲的很透彻
从底至顶(提前阻断)
此方法为本题的最优解法,但“从底至顶”的思路不易第一时间想到。
思路是对二叉树做先序遍历,从底至顶返回子树最大高度,若判定某子树不是平衡树则 “剪枝” ,直接向上返回。
算法流程:
recur(root):
递归返回值:
- 当节点root 左 / 右子树的高度差 < 2 :则返回以节点root为根节点的子树的最大高度,即节点 root 的左右子树中最大高度加 1 ( max(left, right) + 1 );
- 当节点root 左 / 右子树的高度差≥2 :则返回 −1 ,代表 此子树不是平衡树 。
递归终止条件:
- 当越过叶子节点时,返回高度 0 ;
- 当左(右)子树高度 left== -1 时,代表此子树的 左(右)子树 不是平衡树,因此直接返回 −1 ;
isBalanced(root) :
返回值: 若 recur(root) != 1 ,则说明此树平衡,返回 true ; 否则返回 false 。
复杂度分析:
时间复杂度 O(N): N 为树的节点数;最差情况下,需要递归遍历树的所有节点。
空间复杂度 O(N): 最差情况下(树退化为链表时),系统递归需要使用 O(N)的栈空间。
代码实现
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def isBalanced(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
def get_length(root):
if root is None:
return 0
left_length,right_length = get_length(root.left),get_length(root.right)
if left_length < 0 or right_length<0 or abs(left_length-right_length) > 1:
return -1
return max(left_length,right_length) + 1
return (get_length(root) >= 0)