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


此题同 783. 二叉搜索树节点最小距离
https://leetcode-cn.com/problems/minimum-absolute-difference-in-bst/

力扣重复的题越来越多了
在这里插入图片描述

使用额外空间迭代

输入是二叉排序树,按照中序遍历可以得到这棵树的结点值,此时用双指针的思想遍历结点值即可得到最小值

想要找到升序数组中的最大差值,最简单的想法就是二重循环遍历,但是这样做没有利用到升序的性质
利用i和j两个指针作为标记,对于d = abs(L[i]-L[j]),存在三种情况

  1. d<minn
  2. d=minn
  3. d>minn

对于12,此时i,j的差值小于等于minn,表示至少找到了一组不大于minn的组合,此时j如果往后移动,则一定会大于minn,如果i往后移动,则有可能会小于minn —— i往后移动
对于3,此时i和j的距离过大,i应该往后移动 —— i往后移动

发现这三种情况都对应着i往后移动,那么j何时移动?
在升序数组中,除非两个指针相遇,否则j不应该主动移动,因为j移动就是相当于增加i与j之间的距离,所以只有当i、j相遇的时候,j才需要往后移动

```python
# 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:
        # input : 二叉搜索树
        # 获取升序排列的值
        L = []
        self.helper(root,L)
        # 双指针开始遍历
        i,j=0,1
        minn=abs(L[1]-L[0])
        size = len(L)

        while i<size and j<size:
            # 避免计算相同节点,j往后移动
            if i==j:
                j+=1
                continue
            # 更新minn
            if abs(L[j]-L[i]) < minn:
                minn=abs(L[j]-L[i])     
            i+=1 # 总是尝试移动i

        return minn
        

    def helper(self,root,L):
        if root:
            self.helper(root.left,L)
            L.append(root.val)
            self.helper(root.right,L)

按照分析写出代码后发现,i与j的距离总是不会大于1,相当于i、j不断取两两相接的数进行差值判断,所以上面的while循环可以改为

        while i<size and j<size:
            # 更新minn
            if abs(L[j]-L[i]) < minn:
                minn=abs(L[j]-L[i])     
            i+=1 
            j+=1

其实这个规律表示,在有序数组里面,最小的差值一定来自相接的两两元素之间

当然这个two point的遍历只有在数组有序的情况下可以使用,如果无序情况下最好的做法还是排序然后再使用two point

代码的时间复杂度为 O ( N ) O(N) O(N),空间复杂度为 O ( N ) O(N) O(N)

直接递归

在得出的最小的差值一定来自相接的两两元素之间结论后,可以想到,如果在递归过程中,保存当前结点的前驱,那么就可以得到与上一个结点的差值

# 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:
        # python中常量不可变,需要维护全局变量
        self.minn = abs(root.val - (root.left.val if root.left else root.right.val))
        self.pre = None
        self.helper(root)
        return self.minn

    def helper(self,root):
        if root:
            self.helper(root.left)
            if self.pre:
                self.minn=min(self.minn,abs(self.pre.val-root.val))
            self.pre=root
            self.helper(root.right)

遍历依然采用中序遍历,需要注意的是pre和minn必须存储成类内成员变量,而不是作为参数传递进去

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值