leetcode
leetcode 1451 ~ 1500
检查两棵二叉表达式树是否等价

检查两棵二叉表达式树是否等价

难度:

标签:

题目描述

代码结果

运行时间: 270 ms, 内存: 17.9 MB


/*
 * LeetCode 1612: Check If Two Expression Trees are Equivalent
 * Given two binary expression trees, return true if the two binary trees are equivalent.
 * The equivalent of a binary tree is defined as the trees have the same structure and the same leaf nodes in the same order.
 * 
 * Approach:
 * 1. Perform an in-order traversal of both trees.
 * 2. Collect leaf nodes in the order they appear using streams.
 * 3. Compare the two lists of leaf nodes.
 */

import java.util.*;
import java.util.stream.Collectors;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

public class Solution {
    public boolean checkEquivalence(TreeNode root1, TreeNode root2) {
        List<Integer> leaves1 = getLeaves(root1);
        List<Integer> leaves2 = getLeaves(root2);
        return leaves1.equals(leaves2);
    }
    
    private List<Integer> getLeaves(TreeNode node) {
        if (node == null) return new ArrayList<>();
        if (node.left == null && node.right == null) return Arrays.asList(node.val);
        return Stream.concat(getLeaves(node.left).stream(), getLeaves(node.right).stream()).collect(Collectors.toList());
    }
}

解释

方法:

这个题解采用了深度优先搜索(DFS)来遍历两棵二叉表达式树,同时使用一个数组来统计每个字母节点的出现次数。在第一次DFS遍历时,遍历root1树,对每个字母节点增加其出现次数。在第二次DFS遍历时,遍历root2树,对每个字母节点减少其在数组中的计数。最后,检查数组中的所有值是否都为0,以确定两棵树是否等价。此方法假设表达式树只包含小写字母和'+'节点。

时间复杂度:

O(n)

空间复杂度:

O(h)

代码细节讲解

🦆
在这种方法中,为什么在处理第二棵树时选择将数组中的计数值取反而不是继续使用加法?
在处理第二棵树时选择将数组中的计数值取反,是为了通过减法操作来抵消第一棵树中相应字母的计数。这样做的好处是,如果两棵树结构等价,那么所有字母的最终计数应该都会归零,即所有在第一棵树中增加的计数都会被第二棵树中相同的字母减去。如果仍然使用加法,我们则需要在最后对每个字母计数进行检查,确保它们是否都为零,这实际上增加了操作的复杂性。使用取反后的减法可以直接在遍历第二棵树时完成这一验证步骤,使逻辑更为直接和清晰。
🦆
这个解法中的DFS是否能够正确处理树中存在的非字母和'+'以外的其他操作符或节点类型?
这个解法主要是针对只包含字母和'+'节点的表达式树设计的。如果树中存在其他类型的操作符或节点(比如'-'、'*'等),当前的DFS方法将无法正确处理,因为它只识别字母和'+'。对于包含其他操作符的情况,需要对DFS方法进行适当的修改或扩展,以确保能够正确解析和计算这些不同类型的节点。
🦆
如果树的结构相同但是节点排列顺序不同(比如左右子树互换),这种方法是否还能判断两棵树等价?
是的,这种方法仍然可以判断两棵树是否等价,即使它们的左右子树被互换。因为此方法基于对字母的计数而不是树的具体结构。只要两棵树包含相同数量的每个字母,无论这些字母的具体位置如何,最终的字母计数都应该归零,表明两棵树是等价的。这种方法有效地抽象了树的结构,只关注了节点的内容。
🦆
你是如何保证递归过程中不会出现栈溢出错误,尤其是在处理非常深的树时?
确保递归过程中不出现栈溢出错误通常依赖于树的最大深度和系统的栈大小。在实际应用中,可以通过几种方法来减少栈溢出的风险:1. 使用尾递归优化,虽然Python默认不支持尾递归优化,但可以通过代码重构模拟。2. 如果可能,转换为使用迭代的方法,如使用栈来模拟递归过程。3. 增加系统的栈大小(如果环境允许)。4. 在设计上尽量保持树的平衡,避免创建极端不平衡的树结构。对于特别深的树,更推荐使用迭代方法处理,以避免递归深度过大引起的问题。

相关问题