跳至主要內容

617, 合并二叉树

Mike大约 5 分钟binary treeeasybinary treedepth first searchbreadth first search

一、题目描述

给你两棵二叉树:root1root2

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为null的节点将直接作为新二叉树的节点。

返回合并后的二叉树。

注意:合并过程必须从两个树的根节点开始。

示例 1

输入: root1 = [1, 3, 2, 5], root2 = [2, 1, 3, null, 4, null, 7]
输出: [3, 4, 5, 5, 4, null, 7]

示例 2
输入: root1 = [1], root2 = [1, 2]
输出: [2, 2]

提示

  • 两棵树中的节点数目在范围[0, 2000]
  • -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,
        }
    }
}

方法 1: 深度优先搜索

pub fn merge_trees(root1: Option<Rc<RefCell<TreeNode>>>, root2: Option<Rc<RefCell<TreeNode>>>) -> Option<Rc<RefCell<TreeNode>>> {
    //Self::dfs_recur_create_new(root1, root2)
    //Self::dfs_iter_create_new(root1, root2)
    //Self::dfs_recur_reuse(root1, root2)
    Self::dfs_iter_reuse(root1, root2)
}

///
/// 深度优先搜索,递归,创建一个新节点
///
fn dfs_recur_create_new(
    root1: Option<Rc<RefCell<TreeNode>>>,
    root2: Option<Rc<RefCell<TreeNode>>>,
) -> Option<Rc<RefCell<TreeNode>>> {
    const MERGE: fn(
        Option<Rc<RefCell<TreeNode>>>,
        Option<Rc<RefCell<TreeNode>>>,
    ) -> Option<Rc<RefCell<TreeNode>>> = |root1, root2| match (root1, root2) {
        (None, r2) => r2,
        (r1, None) => r1,
        (Some(r1), Some(r2)) => {
            let mut r1 = r1.borrow_mut();
            let mut r2 = r2.borrow_mut();
            let root = Rc::new(RefCell::new(TreeNode::new(r1.val + r2.val)));

            root.borrow_mut().left = MERGE(r1.left.take(), r2.left.take());
            root.borrow_mut().right = MERGE(r1.right.take(), r2.right.take());

            Some(root)
        }
    };

    MERGE(root1, root2)
}

///
/// 深度优先搜索,迭代,创建一个新节点
///
fn dfs_iter_create_new(
    root1: Option<Rc<RefCell<TreeNode>>>,
    root2: Option<Rc<RefCell<TreeNode>>>,
) -> Option<Rc<RefCell<TreeNode>>> {
    let mut root = None;
    let mut stack = vec![(None, root1, root2, false)];

    while let Some((parent, r1, r2, is_left)) = stack.pop() {
        let node = match (r1, r2) {
            (None, r2) => r2,
            (r1, None) => r1,
            (Some(r1), Some(r2)) => {
                let mut r1 = r1.borrow_mut();
                let mut r2 = r2.borrow_mut();
                let node = Some(Rc::new(RefCell::new(TreeNode::new(r1.val + r2.val))));

                if r1.right.is_some() || r2.right.is_some() {
                    stack.push((node.clone(), r1.right.take(), r2.right.take(), false));
                }
                if r1.left.is_some() || r2.left.is_some() {
                    stack.push((node.clone(), r1.left.take(), r2.left.take(), true));
                }

                node
            }
        };

        if let Some(p) = parent {
            if is_left {
                p.borrow_mut().left = node;
            } else {
                p.borrow_mut().right = node;
            }
        } else {
            root = node;
        }
    }

    root
}

///
/// 深度优先搜索,递归,重复使用root1
///
fn dfs_recur_reuse(
    root1: Option<Rc<RefCell<TreeNode>>>,
    root2: Option<Rc<RefCell<TreeNode>>>,
) -> Option<Rc<RefCell<TreeNode>>> {
    const MERGE: fn(
        Option<Rc<RefCell<TreeNode>>>,
        Option<Rc<RefCell<TreeNode>>>,
    ) -> Option<Rc<RefCell<TreeNode>>> = |root1, root2| match (root1, root2) {
        (None, r2) => r2,
        (r1, None) => r1,
        (Some(r1), Some(r2)) => {
            r1.borrow_mut().val += r2.borrow().val;
            let r1_l = r1.borrow_mut().left.take();
            let r2_l = r2.borrow_mut().left.take();
            let r1_r = r1.borrow_mut().right.take();
            let r2_r = r2.borrow_mut().right.take();

            r1.borrow_mut().left = MERGE(r1_l, r2_l);
            r1.borrow_mut().right = MERGE(r1_r, r2_r);

            Some(r1)
        }
    };

    MERGE(root1, root2)
}

///
/// 深度优先搜索,迭代,重复使用root1
///
fn dfs_iter_reuse(
    root1: Option<Rc<RefCell<TreeNode>>>,
    root2: Option<Rc<RefCell<TreeNode>>>,
) -> Option<Rc<RefCell<TreeNode>>> {
    // Ensure that r1 is not None
    if root1.is_none() {
        return root2;
    }
    let mut stack = vec![(root1.clone(), root2)];

    while let Some((root1, root2)) = stack.pop() {
        match (root1, root2) {
            (Some(r1), Some(r2)) => {
                let mut r1 = r1.borrow_mut();
                let mut r2 = r2.borrow_mut();

                r1.val += r2.val;
                if r1.left.is_none() {
                    r1.left = r2.left.take();
                } else {
                    stack.push((r1.left.clone(), r2.left.clone()));
                }
                if r1.right.is_none() {
                    r1.right = r2.right.take();
                } else {
                    stack.push((r1.right.clone(), r2.right.clone()));
                }
            }
            _ => {}
        }
    }

    root1
}

方法 2: 广度优先搜索

pub fn merge_trees(root1: Option<Rc<RefCell<TreeNode>>>, root2: Option<Rc<RefCell<TreeNode>>>) -> Option<Rc<RefCell<TreeNode>>> {
    //Self::bfs_iter_create_new(root1, root2)
    Self::bfs_iter_reuse(root1, root2)
}

///
/// 广度优先搜索,迭代,创建一个新节点
///
fn bfs_iter_create_new(
    root1: Option<Rc<RefCell<TreeNode>>>,
    root2: Option<Rc<RefCell<TreeNode>>>,
) -> Option<Rc<RefCell<TreeNode>>> {
    let mut root = None;
    let mut queue = VecDeque::from([(None, root1, root2, false)]);

    while let Some((parent, r1, r2, is_left)) = queue.pop_front() {
        let node = match (r1, r2) {
            (None, r2) => r2,
            (r1, None) => r1,
            (Some(r1), Some(r2)) => {
                let mut r1 = r1.borrow_mut();
                let mut r2 = r2.borrow_mut();
                let new = Some(Rc::new(RefCell::new(TreeNode::new(r1.val + r2.val))));

                if r1.left.is_some() || r2.left.is_some() {
                    queue.push_back((new.clone(), r1.left.take(), r2.left.take(), true));
                }
                if r1.right.is_some() || r2.right.is_some() {
                    queue.push_back((new.clone(), r1.right.take(), r2.right.take(), false));
                }

                new
            }
        };

        if let Some(p) = parent {
            if is_left {
                p.borrow_mut().left = node;
            } else {
                p.borrow_mut().right = node;
            }
        } else {
            root = node;
        }
    }

    root
}

///
/// 广度优先搜索,迭代,重复使用root1
///
fn bfs_iter_reuse(
    root1: Option<Rc<RefCell<TreeNode>>>,
    root2: Option<Rc<RefCell<TreeNode>>>,
) -> Option<Rc<RefCell<TreeNode>>> {
    // Ensure that r1 is not None
    if root1.is_none() {
        return root2;
    }
    let mut queue = VecDeque::from([(root1.clone(), root2)]);

    while let Some((r1, r2)) = queue.pop_front() {
        match (r1, r2) {
            (Some(r1), Some(r2)) => {
                let mut r1 = r1.borrow_mut();
                let mut r2 = r2.borrow_mut();

                r1.val += r2.val;
                if r1.left.is_none() {
                    r1.left = r2.left.take();
                } else {
                    queue.push_back((r1.left.clone(), r2.left.clone()));
                }
                if r1.right.is_none() {
                    r1.right = r2.right.take();
                } else {
                    queue.push_back((r1.right.clone(), r2.right.clone()));
                }
            }
            _ => {}
        }
    }

    root1
}