872. Leaf-Similar Trees [Easy]

/**
 * 自己的代码
 * 前序遍历找到的叶子节点顺序就是题中要求的从左到右的顺序
 * 用两个stack对root1和root2做前序遍历,先在root1中找到一个叶子节点,再在root2中找到一个叶子节点,比较两者
 * 一旦不同就return false,否则继续寻找下一个叶子节点
 * Runtime: 0 ms, faster than 100.00%
 * Memory Usage: 36.3 MB, less than 95.58%
 */
class Solution {
    public boolean leafSimilar(TreeNode root1, TreeNode root2) {
        Deque<TreeNode> s1 = new LinkedList<>(); // 前序遍历root1的stack
        Deque<TreeNode> s2 = new LinkedList<>(); // 前序遍历root2的stack
        s1.push(root1);
        s2.push(root2);
        while (!s1.isEmpty() && !s2.isEmpty()) {
            int leaf = -1; // 本次循环中要找的相同叶子节点的值
            while (!s1.isEmpty()) {
                TreeNode curr = s1.pop();
                if (curr.left == null && curr.right == null) { // 找到叶子节点,更新leaf的值并暂停遍历root1
                    leaf = curr.val;
                    break;
                }
                if (curr.right != null)
                    s1.push(curr.right);
                if (curr.left != null)
                    s1.push(curr.left);
            }
            while (!s2.isEmpty()) {
                TreeNode curr = s2.pop();
                if (curr.left == null && curr.right == null) { // 找到叶子节点,比较是否与root1找到的leaf值相同,不同则return false,相同则暂停遍历root2,开始寻找和比较下一个叶子节点的循环
                    if (curr.val != leaf)
                        return false;
                    break;
                }
                if (curr.right != null)
                    s2.push(curr.right);
                if (curr.left != null)
                    s2.push(curr.left);
            }
        }
        return s1.isEmpty() && s2.isEmpty(); // 到这句说明两树在遍历过程中的所有叶子节点相同,若两树都遍历完成,则leaf-similar,return true;否则两树叶子节点个数不同,return false
    }
}
/**
 * recursive DFS,得到两个树的完整leaf value sequence,再比较是否相同
 * 可以像这样用StringBuilder存储两个树的leaf value sequence,再转换成字符串判断equals
 * 也可以用list存储和比较,list也有equals方法
 * 相比于上一个方法,不能在第一个不同节点出现时就结束
 * Runtime: 0 ms, faster than 100.00%
 * Memory Usage: 37 MB, less than 23.58% 
 */
class Solution {
    public boolean leafSimilar(TreeNode root1, TreeNode root2) {
        StringBuilder sb1 = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();
        preOrder(root1, sb1);
        preOrder(root2, sb2);
        return sb1.toString().equals(sb2.toString());
    }
    private void preOrder(TreeNode root, StringBuilder sb) {
        if (root == null)
            return;
        if (root.left == null && root.right == null) {
            sb.append(root.val);
            sb.append("-"); // 注意必须给每两个值之间加分隔符,eg. 如果不加分割,值为1、2的两个节点与值为12的一个节点,结果相同
            return;
        }
        preOrder(root.left, sb);
        preOrder(root.right, sb);
    }
}
/**
 * 和上一个方法完全一样只是将StringBuilder换成List
 * Runtime: 0 ms, faster than 100.00%
 * Memory Usage: 36.7 MB, less than 49.10%
 */
class Solution {
    public boolean leafSimilar(TreeNode root1, TreeNode root2) {
        List<Integer> l1 = new ArrayList<>();
        List<Integer> l2 = new ArrayList<>();
        preOrder(root1, l1);
        preOrder(root2, l2);
        return l1.equals(l2);
    }
    private void preOrder(TreeNode root, List<Integer> l) {
        if (root == null)
            return;
        if (root.left == null && root.right == null) {
            l.add(root.val);
            return;
        }
        preOrder(root.left, l);
        preOrder(root.right, l);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值