【Leetcode】二叉树问题整理笔记 之 二叉搜索树



二叉树结构体定义

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None


求二叉搜索树中最小的任意两个节点的值

530. Minimum Absolute Difference in BST

783. Minimum Distance Between BST Nodes 重复。


783. Minimum Distance Between BST Nodes

n/a
n/a

Solution:

除了把所有值都取出来,想不到有什么更好的办法。因为是搜索二叉树,所以使用中序遍历的方式取值。

class Solution:
    def recursive_inorder_traversal(self, root):
        [...code from 94...]

    def min_diff_in_BST(self, root):
        vals = self.recursive_inorder_traversal(root)
        for i in range(1, len(vals)):
            vals[i-1] = vals[i] - vals[i-1]
        vals.pop()
        return min(vals)

    def minDiffInBST(self, root: TreeNode) -> int:
        return self.min_diff_in_BST(root)


98. Validate Binary Search Tree – 检查给定树是否是二叉搜索树

n/a
n/a

Solution:

关键在于确保:

  • 当前结点下的左子树中的最大值必须要小于当前结点值
  • 当前结点下的右子树中的最小值必须要大于当前结点值
class Solution:
    def is_valid_BST(self, root):
        if root is None:
            raise RuntimeError("can't pass NoneType as paremter")

        _max = root.val
        _min = root.val
        if root.left:
            ret = self.is_valid_BST(root.left)
            if ret is False:
                return False
            if ret[1] < root.val:
                _min = ret[0]
            else:
                return False
        if root.right:
            ret = self.is_valid_BST(root.right)
            if ret is False:
                return False
            if ret[0] > root.val:
                _max = ret[1]
            else:
                return False
        return _min, _max

    def isValidBST(self, root: TreeNode) -> bool:
        if root is None:
            return True
        return self.is_valid_BST(root) is not False

n/a



700. Search in a Binary Search Tree - 实现二叉搜索树的“搜索”功能

n/a
n/a

Solution:

class Solution:
    def search_bst(self, root, key):
        if root is None:
            return None
        
        if key < root.val:
            return self.search_bst(root.left, key)
        if key > root.val:
            return self.search_bst(root.right, key)
        return root

    def searchBST(self, root: TreeNode, val: int) -> TreeNode:
        return self.search_bst(root, val)

n/a



938. Range Sum of BST

Given the root node of a binary search tree, return the sum of values of all nodes with value between L and R (inclusive).

The binary search tree is guaranteed to have unique values.

n/a

Solution:

class Solution:
    def tree_sum(self, root):
        if root is None:
            return 0
        
        ret = root.val
        ret += self.tree_sum(root.left)
        ret += self.tree_sum(root.right)
        return ret
    
    def greater_than_sum(self, root, L: int) -> int:
        if root.val == L:
            return root.val + self.tree_sum(root.right)
        if root.val < L:
            return self.greater_than_sum(root.right, L)
        if root.val > L:
            ret = root.val
            ret += self.tree_sum(root.right)
            ret += self.greater_than_sum(root.left, L)
            return ret
    
    def less_than_sum(self, root, R: int) -> int:
        if root.val == R:
            return root.val + self.tree_sum(root.left)
        if root.val > R:
            return self.less_than_sum(root.left, R)
        if root.val < R:
            ret = root.val
            ret += self.tree_sum(root.left)
            ret += self.less_than_sum(root.right, R)
            return ret

    def range_sum(self, root, L: int, R: int) -> int:
        if root.val < L:
            return self.range_sum(root.right, L, R)
        if root.val > R:
            return self.range_sum(root.left, L, R)
        
        # now, root in the middle of [L, R]
        ret = root.val
        if L < root.val < R:
            ret += self.greater_than_sum(root.left, L)
            ret += self.less_than_sum(root.right, R)
        elif root.val == L:
            ret += self.less_than_sum(root.right, R)
        else:
            ret += self.greater_than_sum(root.left, L)
        return ret
            
    def rangeSumBST(self, root: TreeNode, L: int, R: int) -> int:
        return self.range_sum(root, L, R)

n/a



230. Kth Smallest Element in a BST

Given a binary search tree, write a function kthSmallest to find the kth smallest element in it.

Note:
You may assume k is always valid, 1 ≤ k ≤ BST’s total elements.

Example 1:

Input: root = [3,1,4,null,2], k = 1

  3
 / \
1   4
 \
  2

Output: 1

Example 2:

Input: root = [5,3,6,2,4,null,null,1], k = 3

       5
      / \
     3   6
    / \
   2   4
  /
 1

Output: 3

Follow up:
What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?

Solution:

class FoundException(Exception):
    pass


class Solution:
    def recursive(self, root, k):
        new_key = k
        if root.left:
            new_key = self.recursive(root.left, k)

        # end, i am the smallest of (sub-)tree
        if new_key == 1:
            raise FoundException(root.val)
        elif root.right:
            new_key = self.recursive(root.right, new_key - 1)
            return new_key
        else:
            return new_key - 1

    def kthSmallest(self, root: TreeNode, k: int) -> int:
        try:
            self.recursive(root, k)
        except FoundException as err:
            return int(str(err))

虽然知道这种解法效率相对是比较低的 O ( k ) O(k) ,应该有更好的解法(注意到题目的 “Follow up”);但是一时想不出来,所以还是先解决掉再说。这个问题应该还算有些意思,所以后面看看 Solution 之后再用新Solution解一遍。

n/a



653. Two Sum IV - Input is a BST

n/a

Given a Binary Search Tree and a target number, return true if there exist two elements in the BST such that their sum is equal to the given target.

Example 1:

Input: 
    5
   / \
  3   6
 / \   \
2   4   7

Target = 9

Output: True

Example 2:

Input: 
    5
   / \
  3   6
 / \   \
2   4   7

Target = 28

Output: False

Solution:

class Solution:
    def _lnr(self, root) -> list:
        if root is None:
            return []

        ret = []
        ret.extend(self._lnr(root.left))
        ret.append(root.val)
        ret.extend(self._lnr(root.right))
        return ret

    def findTarget(self, root: TreeNode, k: int) -> bool:
        arr = self._lnr(root)
        if len(arr) <= 1:
            return False

        l = 0
        r = len(arr) - 1
        while l < r:
            sum_ = arr[l] + arr[r]
            if sum_ > k:
                r -= 1
            elif sum_ < k:
                l += 1
            else:  # sum_ == k
                return True
        return False

submit:

n/a

其中使用了中序遍历获得排序的数组。
然后从数组两头移动得到相加等于 target 的“下标”(不过不需要返回下标,只需要返回是否存在相加可以等于 target 的两个值的结论即可)。



Reference



发布了164 篇原创文章 · 获赞 76 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qq_29757283/article/details/96476523