Leetcode 108:将有序数组转换为二叉搜索树(最详细的解法!!!)

将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。

本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

示例:

给定有序数组: [-10,-3,0,5,9],

一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:

      0
     / \
   -3   9
   /   /
 -10  5

    1
    2
    3
    4
    5
    6
    7
    8
    9

解题思路

我们回到这样的一种性质:对于一个二叉搜索树来说,它的中序遍历是一个有序数组。所以,这个问题的另一种表述就是:通过一颗二叉搜索树的中序遍历,推导出这颗二叉搜索树的形状。但是这样推导出来的二叉搜索树形状有很多,所以题目又限定了这样的条件高度平衡二叉搜索树,但是依旧会出现很多答案,但是没关系,我们只要有一种解就可以啦。例如,有序数组[-10, -3, -1, -0, 9],我们有如下几种情况

      -1                           0
     /   \                        / \
   -10    0          and        -3   9
     \     \                   /  \
      -3    9                -10  -1

    1
    2
    3
    4
    5

平衡二分搜索树有这样的性质:左子树的值小于右子树的值。所以,我们可以每次去数组的中间值,作为二分搜索树的中间节点,依次递归下去即可。

class Solution:
    def _sortedArrayToBST(self, nums, start, end):
        if start > end:
            return None
        
        mid = (end - start)//2 + start
        midNode = TreeNode(nums[mid])
        midNode.left = self._sortedArrayToBST(nums, start, mid - 1)
        midNode.right = self._sortedArrayToBST(nums, mid + 1, end)
        return midNode
        
    def sortedArrayToBST(self, nums):
        """
        :type nums: List[int]
        :rtype: TreeNode
        """
        return self._sortedArrayToBST(nums, 0, len(nums) - 1)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

我们同样希望可以通过迭代来解决这个问题。

class Solution:
    def sortedArrayToBST(self, nums):
        """
        :type nums: List[int]
        :rtype: TreeNode
        """
        root, stack = None, [(0, len(nums)-1, None, None)]
        while stack:
            start, end, l_parent, r_parent = stack.pop()
            if start > end:
                continue
                
            mid = start + (end - start)//2
            node = TreeNode(nums[mid])
            root = root or node
            if l_parent:
                l_parent.right = node
                
            if r_parent:
                r_parent.left = node
                
            stack.append((start, mid-1, None, node))
            stack.append((mid+1, end, node, None))
            
        return root

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!
---------------------
作者:coordinate_blog
来源:CSDN
原文:https://blog.csdn.net/qq_17550379/article/details/82414300
版权声明:本文为博主原创文章,转载请附上博文链接!

posted @ 2019-07-28 11:23  天涯海角路  阅读(118)  评论(0)    收藏  举报