代码随想录第23天|108. 将有序数组转换为二叉搜索树, 538. 把二叉搜索树转换为累加树, 669. 修剪二叉搜索树

116 阅读2分钟

108. 将有序数组转换为二叉搜索树

1. fist idea

The ordered list need to be conveted to a Binary Search Tree.

  1. We can find the midpoint of the current list.
  2. The left segment of the list is the left tree.
  3. The right segment of the list is the right tree.
  4. The midpoint will be the current root.
  5. If the left segment is empty, the left child of the root is None.
  6. Vice-versa.
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
        if len(nums) == 0:
            return None
        mid_idx = len(nums) // 2
        left_child = self.sortedArrayToBST(nums[:mid_idx])
        right_child = self.sortedArrayToBST(nums[mid_idx + 1:])
        return TreeNode(val=nums[mid_idx], left=left_child, right=right_child)

2. learning time

20min.

538. 把二叉搜索树转换为累加树

1. first idea

These is a double-point question.

We need to traversal the tree from the right-most leaf of the whole tree.

The previous point is point at the root which has already store the sum of its subtree.

The current point is point at the node which waits to add the value of previous point.

If the addition to the current point has happened, we need to go ahead, this should obey the mid-order traversal:

  1. pre_point = cur_point
  2. If cur_point has left child, cur_point = cur_point.left
  3. If cur_point do not has left child, we need to jump back to the previous recursive level. cur_point at this level is the cur_point.
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def __init__(self):
        self.pre_pt = None

    def mid_traversal(self, cur_pt):
        if cur_pt.right:
            self.mid_traversal(cur_pt=cur_pt.right)
        if self.pre_pt:
            cur_pt.val += self.pre_pt.val
        self.pre_pt = cur_pt
        if cur_pt.left:
            self.mid_traversal(cur_pt=cur_pt.left)

    def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if not root:
            return None
        self.mid_traversal(root)
        return root

2. learning time

33min.

669. 修剪二叉搜索树

1. first idea

There are some occasions:

  1. If the current root is in [low,high][low, high]
    • The current root need to be keep.
    • recurse to the root.left to get the new left child.
    • recurse to the root.right to get the new right child.
  2. If the current root is in (,low](-\infin, low]
    • Remove the root, but keep the right sub-tree.
    • The node in right sub-tree may be still in (,low](-\infin, low], we need to recurse to the right sub-tree to get the new right child.
    • return the right child as the new current root.
  3. If the current root is in [high,+)[high, +\infin)
    • Vice-versa, remove the root, but keep the left sub-tree.
    • Recurse to the left sub-tree to get the new left child.
    • Return the left child as the new current root.
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
        if not root:
            return None
        else:
            if low <= root.val <= high:
                root.left = self.trimBST(root.left, low, high)
                root.right = self.trimBST(root.right, low, high)
                return root
            if root.val < low:
                return self.trimBST(root.right, low, high)
            if root.val > high:
                return self.trimBST(root.left, low, high)

2. learning time

22min. (I don't understand where the difficulties are?)