跳至主要內容

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

Mike大约 2 分钟binary treeeasybinary treebinary search treedepth first searchbreadth first search

一、题目描述

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

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

示例 1

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

示例 2

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

提示

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

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

相关主题

  • 深度优先搜索
  • 广度优先搜索
  • 二叉搜索树
  • 二叉树

二、题解

#[derive(Debug, PartialEq, Eq)]
pub struct TreeNode {
    pub val: i32,
    pub left: Option<Rc<RefCell<TreeNode>>>,
    pub right: Option<Rc<RefCell<TreeNode>>>,
}

impl TreeNode {
    #[inline]
    pub fn new(val: i32) -> Self {
        TreeNode {
            val,
            left: None,
            right: None,
        }
    }
}

方法 1: 中序遍历

pub fn get_minimum_difference(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
    Self::in_order_recur(root)
    //Self::in_order_iter(root)
}

fn in_order_recur(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
    let mut min_abs_diff = i32::MAX;
    let mut prev_val = None;
    const IN_ORDER: fn(Option<Rc<RefCell<TreeNode>>>, &mut i32, &mut Option<i32>) =
        |root, min_abs_diff, prev_val| {
            if let Some(curr) = root {
                IN_ORDER(curr.borrow_mut().left.take(), min_abs_diff, prev_val);

                let curr_val = curr.borrow().val;
                prev_val.map(|prev_val| {
                    let diff = curr_val - prev_val;
                    if diff < *min_abs_diff {
                        *min_abs_diff = diff;
                    }
                });
                *prev_val = Some(curr_val);

                IN_ORDER(curr.borrow_mut().right.take(), min_abs_diff, prev_val);
            }
        };

    IN_ORDER(root, &mut min_abs_diff, &mut prev_val);

    min_abs_diff
}

fn in_order_iter(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
    let mut min_abs_diff = i32::MAX;
    let mut prev_val = None;

    if let Some(root) = root {
        let mut stack = vec![Ok(root)];

        while let Some(curr) = stack.pop() {
            match curr {
                Ok(node) => {
                    if let Some(right) = node.borrow_mut().right.take() {
                        stack.push(Ok(right));
                    }

                    stack.push(Err(node.borrow().val));

                    if let Some(left) = node.borrow_mut().left.take() {
                        stack.push(Ok(left));
                    }
                }
                Err(curr_val) => {
                    prev_val.map(|prev_val| {
                        let diff = curr_val - prev_val;
                        if diff < min_abs_diff {
                            min_abs_diff = diff;
                        }
                    });

                    prev_val = Some(curr_val);
                }
            }
        }
    }

    min_abs_diff
}