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

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


题目来源:力扣(LeetCode)https://leetcode-cn.com/problems/minimum-absolute-difference-in-bst/

题目


给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。

示例:

输入:

   1
    \
     3
    /
   2

输出:
1

解释:
最小绝对差为 1,其中 2 和 1 的差的绝对值为 1(或者 2 和 3)。

提示:

  • 树中至少有 2 个节点。
  • 本题与 783 https://leetcode-cn.com/problems/minimum-distance-between-bst-nodes/ 相同

解题思路


思路:中序遍历(递归、迭代)

先审题,题目给定一个二叉搜索树,且所有节点为非负值,要求树中任意两节点的差的绝对值的最小值。

这里,题目给定的是二叉搜索树。关于二叉搜索树(BST)的定义:

  • 结点左子树中所含结点的值小于等于当前结点的值
  • 结点右子树中所含结点的值大于等于当前结点的值
  • 左子树和右子树都是二叉搜索树

根据上面 BST 的定义,我们知道,中序遍历 BST 得到的序列是递增序列。

当存在一个元素值均为非负值且递增的序列时,相邻两个元素的差值中可取得最小值。

假设存在元素 x 1 , x 2 , x 3 x_1, x_2, x_3 x1,x2,x3,其中 x 1 < x 2 < x 3 x_1 < x_2 < x_3 x1<x2<x3,那么我们很容易得到 x 2 − x 1 < x 3 − x 1 x_2 - x_1 < x_3 - x_1 x2x1<x3x1

即是,在递增序列中,要求任意两个元素的差值绝对值的最小值,那这个最小值会在相邻两个元素中差值取得。

现在我们知道,中序遍历二叉搜索树的结果会是一个递增序列,那么我们可以在处理节点值的时候,通过比较相邻元素差值,得到最小值。具体的做法:

  • 定义变量 pre 记录前驱节点,初始化为 -1
  • 定义变量 ans 存储最小值,初始化为 float('inf')
  • 遍历的同时,计算当前节点与 pre 的差值,与 ans 比较取较小值。同时维护更新 pre。

递归

首先,先看递归方法如何实现。

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

class Solution:
    def getMinimumDifference(self, root: TreeNode) -> int:
        # 定义变量 ans 存储最小值,初始化为 float('inf')
        ans = float('inf')
        # pre 记录前驱节点
        pre = -1

        def dfs(root):
            nonlocal ans, pre
            if not root:
                return
            
            dfs(root.left)
            # 节点值处理,
            if pre != -1:
                # 比较相邻元素差值,取最小值
                ans = min(ans, root.val-pre)
            # 维护更新 pre
            pre = root.val
            dfs(root.right)

        dfs(root)
		
        return ans

迭代

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

class Solution:
    def getMinimumDifference(self, root: TreeNode) -> int:
		# pre 记录前驱节点
        pre = -1
        cur = root
        ans = float('inf')
		
        stack = []
        
        while cur or stack:
            # 通过指针访问叶子节点
            if cur:
                stack.append(cur)
                cur = cur.left
            else:
                cur = stack.pop()
                # 处理相邻元素差值,
                if pre != -1:
                    ans = min(ans, cur.val - pre)
                # 维护更新 pre
                pre = cur.val
                cur = cur.right
        
        return ans

欢迎关注


公众号 【书所集录】


如有错误,烦请指出,欢迎指点交流。

你可能感兴趣的:(LeetCode,算法,leetcode,中序遍历,递归,迭代)