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

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

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

给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。

差值是一个正数,其数值等于两值之差的绝对值。

示例 1:
在这里插入图片描述

输入:root = [4,2,6,1,3]
输出:1

示例 2:
在这里插入图片描述

输入:root = [1,0,48,null,null,12,49]
输出:1

提示:

  • 树中节点的数目范围是 [2, 10^4]
  • 0 <= Node.val <= 10^5

注意:本题与783. 二叉搜索树节点最小距离 相同

思路

题目中要求在二叉搜索树上任意两节点的差的绝对值的最小值。

注意是二叉搜索树,二叉搜索树可是有序的。

遇到在二叉搜索树上求什么最值啊,差值之类的,就把它想成在一个有序数组上求最值,求差值,这样就简单多了。

递归

那么二叉搜索树采用中序遍历,其实就是一个有序数组。

在一个有序数组上求两个数最小差值,这是不是就是一道送分题了。

最直观的想法,就是把二叉搜索树转换成有序数组,然后遍历一遍数组,就统计出来最小差值了。

Go代码如下:

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func getMinimumDifference(root *TreeNode) int {
    // 二叉搜索树中序遍历后就是有序的,得到数组后,相邻两个数的最小差值就是整棵树两节点之间的最小差值
    arr := make([]int,0)
    dfs(root,&arr)

    res := math.MaxInt32
    for i := 1;i < len(arr);i++ {
        // 因为有序,后一个数减去前一个数一定是正数,不必取绝对值了
        if arr[i] - arr[i-1] < res {
            res = arr[i] - arr[i - 1]
        }
    }

    return res
}

func dfs(root *TreeNode,arr *[]int) {
    if root == nil {
        return
    }

    dfs(root.Left,arr)
    *arr = append(*arr,root.Val)
    dfs(root.Right,arr)
}

在这里插入图片描述

以上代码是把二叉搜索树转化为有序数组了,其实在二叉搜素树中序遍历的过程中,我们就可以直接计算了。

需要用一个pre节点记录一下cur节点的前一个节点。

如图:
在这里插入图片描述

一些同学不知道在递归中如何记录前一个节点的指针,其实实现起来是很简单的,大家只要看过一次,写过一次,就掌握了。

代码如下:

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */

// 中序遍历的同时计算最小值
func minDiffInBST(root *TreeNode) int {
    // 保留前一个节点的指针
    var prev *TreeNode
    // 定义一个比较大的值
    min := math.MaxInt64
    var travel func(node *TreeNode)
    travel = func(node *TreeNode) {
        if node == nil {
            return 
        }
        travel(node.Left)
        if prev != nil && node.Val - prev.Val < min {
            min = node.Val - prev.Val
        }
        prev = node // 记录前一个节点
        travel(node.Right)
    }
    travel(root)
    return min
}

是不是看上去也并不复杂!

迭代

下面我给出其中的一种中序遍历的迭代法,代码如下:

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */

func minDiffInBST(root *TreeNode) int {
    // 保留前一个节点的指针
    var prev *TreeNode
    curTreeNode := root
    res := math.MaxInt64
    stack := make([]*TreeNode,0)

    for curTreeNode != nil || len(stack) != 0 {
        if curTreeNode != nil {
            stack = append(stack,curTreeNode)
            curTreeNode = curTreeNode.Left // 左
        } else {
            curTreeNode = stack[len(stack) - 1] // 中
            stack = stack[0:len(stack) - 1]
            if prev != nil && curTreeNode.Val - prev.Val < res {
                res = curTreeNode.Val - prev.Val
            }
            prev = curTreeNode // 更新前一个节点指向
            curTreeNode = curTreeNode.Right // 右
        }
    }

    return res
   
}

总结

遇到在二叉搜索树上求什么最值,求差值之类的,都要思考一下二叉搜索树可是有序的,要利用好这一特点。

同时要学会在递归遍历的过程中如何记录前后两个指针,这也是一个小技巧,学会了还是很受用的。

后面我将继续介绍一系列利用二叉搜索树特性的题目。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值