代码随想录算法训练营第二十一天 | 530. 二叉搜索树的最小绝对差、501. 二叉搜索树中的众数、236. 二叉树的最近公共祖先

69 阅读2分钟

530. 二叉搜索树的最小绝对差

代码随想录视频讲解

代码随想录文章讲解

递归法

  • BST的中序遍历是有序的,只需要比较中序遍历中相邻两个节点的差值的大小即可
class Solution:
    def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
        pre = None
        min_difference = float('inf')
​
        def _helper(root):
            if not root:
                return
​
            # left
            _helper(root.left)
​
            # root
            nonlocal pre
            nonlocal min_difference
            if pre:
                min_difference = min(min_difference, root.val - pre.val)
            pre = root
​
            # right
            _helper(root.right)
​
        _helper(root)
​
        return min_difference

迭代法

  • 统一迭代法中序遍历
class Solution:
    def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
        min_difference = float('inf')
        stack = deque([root])
        pre = None
        while stack:
            cur = stack.pop()
            if cur:
                # right
                if cur.right:
                    stack.append(cur.right)
​
                # root
                stack.append(cur)
                stack.append(None)
​
                # left
                if cur.left:
                    stack.append(cur.left)
            else:
                node = stack.pop()
                if pre:
                    min_difference = min(min_difference, node.val - pre.val)
                pre = node
​
        return min_difference

501. 二叉搜索树中的众数

代码随想录视频讲解

代码随想录文章讲解

递归法使用dict存储每个节点值出现的个数

class Solution:
    def findMode(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
​
        res = {}
​
        def _traversal(root):
            if not root:
                return
​
            _traversal(root.left)
​
            res[root.val] = res.get(root.val, 0) + 1
​
            _traversal(root.right)
​
        _traversal(root)
        max_num = max(res.values())
​
        return [x[0] for x in res.items() if x[1] == max_num]

递归法利用BST特性

  • 相同的值在中序遍历中一定是相邻的
class Solution:
    def findMode(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
​
        res = []
        pre = None
        count = 0
        max_count = -1
​
        def _traversal(root):
            nonlocal pre
            nonlocal count
            nonlocal max_count
            nonlocal res
​
            if not root:
                return
            # left
            _traversal(root.left)
            # root
            if not pre:
                count = 1
            elif pre.val == root.val:
                count += 1
            else:
                count = 1
            pre = root
​
            if count == max_count:
                res.append(root.val)
            if max_count < count:
                max_count = count
                res = [root.val]
            # right
            _traversal(root.right)
​
        _traversal(root)
​
        return res

236. 二叉树的最近公共祖先

代码随想录视频讲解

代码随想录文章讲解

递归法

  • 首先最容易想到的一个情况:如果找到一个节点,发现左子树出现结点p,右子树出现节点q,或者 左子树出现结点q,右子树出现节点p,那么该节点就是节点p和q的最近公共祖先。
  • 或者,节点本身p(q),它拥有一个子孙节点q(p)
  • 使用后序遍历
class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if root == p or root == q or not root:
            return root
​
        # left
        left = self.lowestCommonAncestor(root.left, p, q)
        # right
        right = self.lowestCommonAncestor(root.right, p, q)
​
        if left and right:
            return root
        if left:
            return left
​
        return right