/**
* 自己的代码
* 前序遍历找到的叶子节点顺序就是题中要求的从左到右的顺序
* 用两个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);
}
}