跳至主要內容

501, 二叉搜索树中的众数

Mike大约 6 分钟binary treeeasybinary treedepth first searchbinary search tree

一、题目描述

给你一个含重复值的二叉搜索树(BST)的根节点root,找出并返回BST中的所有众数open in new window(即出现频率最高的元素)。

如果树中有不止一个众数,可以按任意顺序返回。

假定BST满足如下定义:

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

示例 1

输入: root = [1, null, 2, 2]
输出: [2]

示例 2
输入: root = [0]
输出: [0]

提示

  • 树中节点的数目在范围[1, 10⁴]
  • -10⁵ <= Node.val <= 10⁵

进阶
你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)

相关主题

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

二、题解

#[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,
        }
    }
}

///       val: 正在遍历的节点的值
///  curr_val: 当前节点的值(当前值)
/// curr_freq: 当前值出现的频率
///  max_freq: 频率的最大值
///       res: 最终生成的结果
fn update(val: i32, curr_val: &mut i32, curr_freq: &mut usize, max_freq: &mut usize, res: &mut Vec<i32>) {
    if val == *curr_val {
        *curr_freq += 1;
    } else {
        *curr_val = val;
        *curr_freq = 1;
    }
    if *curr_freq > *max_freq {
        res.clear();
        *max_freq = *curr_freq;
    }
    if *curr_freq == *max_freq {
        res.push(val);
    }
}

方法 1: 使用哈希表

pub fn find_mode(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
    //Self::use_hashmap_recur(root)
    Self::use_hashmap_iter(root)
}

///
/// Time complexity: O(n)
/// Space complexity: O(n)
///
fn use_hashmap_recur(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
    let mut map = HashMap::new();
    const PREORDER: fn(Option<Rc<RefCell<TreeNode>>>, &mut HashMap<i32, usize>) =
        |root, counter| {
            if let Some(curr) = root {
                let curr_val = curr.borrow().val;
                counter
                    .entry(curr_val)
                    .and_modify(|count| *count += 1)
                    .or_insert(1);
                PREORDER(curr.borrow_mut().left.take(), counter);
                PREORDER(curr.borrow_mut().right.take(), counter);
            }
        };

    PREORDER(root, &mut map);

    let max_freq = map.values().max().map(|v| *v).unwrap_or_default();
    map.into_iter()
        .filter_map(|(k, v)| {
            if v == max_freq {
                return Some(k);
            }
            None
        })
        .collect()
}

///
/// Time complexity: O(n)
/// Space complexity: O(n)
///
fn use_hashmap_iter(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
    let mut map = HashMap::new();

    if let Some(root) = root {
        let mut stack = vec![root];
        while let Some(curr) = stack.pop() {
            let curr_val = curr.borrow().val;
            map.entry(curr_val)
                .and_modify(|count| *count += 1)
                .or_insert(1);

            if let Some(right) = curr.borrow_mut().right.take() {
                stack.push(right);
            }
            if let Some(left) = curr.borrow_mut().left.take() {
                stack.push(left);
            }
        }
    }

    let max_freq = map.values().max().map(|v| *v).unwrap_or_default();
    map.into_iter()
        .filter_map(|(k, v)| {
            if v == max_freq {
                return Some(k);
            }
            None
        })
        .collect()
}

方法 2: 中序遍历

pub fn find_mode(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
    //Self::in_order_traversal_recur(root)
    Self::in_order_traversal_iter(root)
}

///
/// Time complexity: O(n)
/// Space complexity: O(n)
///
fn in_order_traversal_recur(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
    let mut res = vec![];
    let mut curr_val = i32::MIN;
    let mut curr_freq = 0;
    let mut max_freq = 0;
    const INORDER: fn(Option<Rc<RefCell<TreeNode>>>, &mut i32, &mut usize, &mut usize, &mut Vec<i32>) = 
        |root, curr_val, curr_freq, max_freq, res| {
            if let Some(curr) = root {
                INORDER(curr.borrow_mut().left.take(), curr_val, curr_freq, max_freq, res);
                
                let val = curr.borrow().val;
                Solution::update(val, curr_val, curr_freq, max_freq, res);
                
                INORDER(curr.borrow_mut().right.take(), curr_val, curr_freq, max_freq, res);
            }
    };

    INORDER(root, &mut curr_val, &mut curr_freq, &mut max_freq, &mut res);

    res
}

///
/// Time complexity: O(n)
/// Space complexity: O(n)
///
fn in_order_traversal_iter(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
    let mut res = vec![];

    if let Some(root) = root {
        let mut curr_val = i32::MIN;
        let mut curr_freq = 0;
        let mut max_freq = 0;
        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(val) => {
                    Solution::update(val, &mut curr_val, &mut curr_freq, &mut max_freq, &mut res);
                }
            }
        }
    }

    res
}

方法 3: Morris中序遍历

pub fn find_mode(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
    //Self::morris_in_order_iter_1(root)
    Self::morris_in_order_iter_2(root)
}

///
/// Time complexity: O(n)
/// Space complexity: O(1)
///
fn morris_in_order_iter_1(mut root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
    let mut res = vec![];
    let mut curr_val = i32::MIN;
    let mut curr_freq = 0;
    let mut max_freq = 0;

    while let Some(curr) = root {
        let val = curr.borrow().val;
        let left = curr.borrow().left.clone();

        if left.is_some() {
            let mut prev_node = left.clone();

            while let Some(ref prev) = prev_node {
                let right = prev.borrow().right.clone();
                if right.is_none() || right == Some(curr.clone()) {
                    break;
                } else {
                    prev_node = right;
                }
            }

            match prev_node {
                None => break, // this is mark code
                Some(prev) => {
                    let mut prev = prev.borrow_mut();

                    if let Some(_) = prev.right.take() {
                        Solution::update(val, &mut curr_val, &mut curr_freq, &mut max_freq, &mut res);
                        root = curr.borrow().right.clone();
                    } else {
                        prev.right = Some(curr);
                        root = left;
                    }
                }
            }
        } else {
            Solution::update(val, &mut curr_val, &mut curr_freq, &mut max_freq, &mut res);
            root = curr.borrow().right.clone();
        };
    }

    res
}

///
/// Time complexity: O(n)
/// Space complexity: O(1)
///
fn morris_in_order_iter_2(mut root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
    let mut res = vec![];
    let mut curr_val = i32::MIN;
    let mut curr_freq = 0;
    let mut max_freq = 0;

    while let Some(curr) = root {
        let left = curr.borrow().left.clone();
        let val = curr.borrow().val;

        if left.is_none() {
            Solution::update(val, &mut curr_val, &mut curr_freq, &mut max_freq, &mut res);
            root = curr.borrow().right.clone();
            continue;
        }

        let mut prev_node = left.clone();
        while let Some(ref prev) = prev_node {
            let right = prev.borrow().right.clone();
            if right.is_none() || right == Some(curr.clone()) {
                break;
            } else {
                prev_node = right;
            }
        }

        if let Some(prev) = prev_node {
            let mut prev = prev.borrow_mut();
            
            if let Some(_) = prev.right.take() {
                Solution::update(val, &mut curr_val, &mut curr_freq, &mut max_freq, &mut res);
                root = curr.borrow().right.clone();
            } else {
                prev.right = Some(curr);
                root = left;
            }
        } else {
            // here is mark code
            //root = None;
            break;
        }
    }

    res
}