一、 102. 二叉树的层序遍历
题目连接:https://leetcode.cn/problems/binary-tree-level-order-traversal/
思路一、迭代法,使用一个队列,将每一层的元素放入到队列中,然后每一层poll();
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new LinkedList<>();
if (root == null) return result;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
int size = queue.size();
List<Integer> list = new ArrayList<>();
while (size-- > 0){
TreeNode treeNode = queue.poll();
list.add(treeNode.val);
if (treeNode.left != null) queue.offer(treeNode.left);
if (treeNode.right != null) queue.offer(treeNode.right);
}
result.add(list);
}
return result;
}
}
思路二、使用递归方法,使用前序遍历,遇到新的层则添加数组,并且将当前层节点的数据添加到数组中去
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private List<List<Integer>> result;
private void levelOrder(TreeNode root, int depth) {
if (root == null) return;
depth++;
//有新的层了,则添加新的数组
if (result.size() < depth) {
List<Integer> list = new ArrayList<>();
result.add(list);
}
//往第几层的数组上添加元素
result.get(depth - 1).add(root.val);
levelOrder(root.left, depth);
levelOrder(root.right, depth);
}
public List<List<Integer>> levelOrder(TreeNode root) {
result = new ArrayList<>();
levelOrder(root, 0);
return result;
}
}
二、 107. 二叉树的层序遍历 II
题目连接:https://leetcode.cn/problems/binary-tree-level-order-traversal-ii/
思路:使用队列,将每层的pop的数据添加到ArrayList,在将每层的集合添加到linkedList中去,使用addFirst(),让最后一层在最前面
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
LinkedList<List<Integer>> result = new LinkedList<>();
if (root != null) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> list = new ArrayList<>();
while (size-- > 0){
TreeNode treeNode = queue.poll();
list.add(treeNode.val);
if (treeNode.left != null) queue.offer(treeNode.left);
if (treeNode.right != null) queue.offer(treeNode.right);
}
result.addFirst(list);
}
}
return result;
}
}
三、 199. 二叉树的右视图
题目连接:https://leetcode.cn/problems/binary-tree-right-side-view/
思路一、使用程序遍历,每个层i == size - 1 即为每一层的最右视图
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root != null) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
int size = queue.size();
for (int i = 0; i < size; i++){
TreeNode treeNode = queue.poll();
if (i == size - 1) {
result.add(treeNode.val);
}
if (treeNode.left != null) queue.offer(treeNode.left);
if (treeNode.right != null) queue.offer(treeNode.right);
}
}
}
return result;
}
}
四、 637. 二叉树的层平均值
题目链接:https://leetcode.cn/problems/average-of-levels-in-binary-tree/
思路:使用层序遍历,计算每一层的总和sum,平均值(double)sum / size
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Double> averageOfLevels(TreeNode root) {
List<Double> result = new ArrayList<>();
if (root != null) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
int size = queue.size();
double sum = 0;
for (int i = 0; i < size; i++) {
TreeNode treeNode = queue.poll();
sum += treeNode.val;
if (treeNode.left != null) queue.offer(treeNode.left);
if (treeNode.right != null) queue.offer(treeNode.right);
}
result.add(sum / size);
}
}
return result;
}
}
五、 429. N 叉树的层序遍历
题目链接:https://leetcode.cn/problems/n-ary-tree-level-order-traversal/
思路一、迭代法
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) return result;
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> list = new ArrayList<>();
while (size -- > 0) {
Node node = queue.poll();
list.add(node.val);
for (int i = 0; node.children != null && i < node.children.size(); i++) {
Node childNode = node.children.get(i);
queue.offer(childNode);
}
}
result.add(list);
}
return result;
}
}
思路二、使用递归
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
private List<List<Integer>> result;
private void levelOrder(Node root, int depth) {
if (root == null) return;
depth++;
//发现新层
if (result.size() < depth) {
List<Integer> list = new ArrayList<>();
result.add(list);
}
//将该层的元素放入结合
result.get(depth - 1).add(root.val);
for (int i = 0; root.children != null && i < root.children.size(); i++) {
levelOrder(root.children.get(i), depth);
}
}
public List<List<Integer>> levelOrder(Node root) {
result = new ArrayList<>();
levelOrder(root, 0);
return result;
}
}
六、515. 在每个树行中找最大值
题目链接:https://leetcode.cn/problems/find-largest-value-in-each-tree-row/
思路:层序遍历,找出每层最大值
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> largestValues(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root != null) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
int max = Integer.MIN_VALUE;
while (size-- > 0) {
TreeNode treeNode = queue.poll();
if (treeNode.val > max) {
max = treeNode.val;
}
if (treeNode.left != null) queue.offer(treeNode.left);
if (treeNode.right != null) queue.offer(treeNode.right);
}
result.add(max);
}
}
return result;
}
}
七、116. 填充每个节点的下一个右侧节点指针
题目链接:https://leetcode.cn/problems/populating-next-right-pointers-in-each-node/
思路一:层序遍历,从右边往左边放入队列中,每个节点的next=上一个节点
/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node next;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, Node _left, Node _right, Node _next) {
val = _val;
left = _left;
right = _right;
next = _next;
}
};
*/
class Solution {
public Node connect(Node root) {
if (root == null) return root;
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
Node nextNode = null;
while (size-- > 0) {
Node node = queue.poll();
node.next = nextNode;
nextNode = node;
if (node.right != null) queue.offer(node.right);
if (node.left != null) queue.offer(node.left);
}
}
return root;
}
}
思路二、递归法 前序遍历
if (root.left != null) {
//左右节点next连好
root.left.next = root.right;
if (root.next != null) {
root.right.next = root.next.left;
}
}
/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node next;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, Node _left, Node _right, Node _next) {
val = _val;
left = _left;
right = _right;
next = _next;
}
};
*/
class Solution {
public Node connect(Node root) {
if (root == null) return root;
if (root.left != null) {
root.left.next = root.right;
if (root.next != null) {
root.right.next = root.next.left;
}
}
connect(root.left);
connect(root.right);
return root;
}
}
八、117. 填充每个节点的下一个右侧节点指针 II
题目链接:https://leetcode.cn/problems/populating-next-right-pointers-in-each-node-ii/
思路一:使用层序遍历
/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node next;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, Node _left, Node _right, Node _next) {
val = _val;
left = _left;
right = _right;
next = _next;
}
};
*/
class Solution {
public Node connect(Node root) {
if (root == null) return root;
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
Node next = null;
while (size-- > 0) {
Node node = queue.poll();
node.next = next;
next = node;
if (node.right != null) queue.offer(node.right);
if (node.left != null) queue.offer(node.left);
}
}
return root;
}
}
思路二、前序遍历法
/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node next;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, Node _left, Node _right, Node _next) {
val = _val;
left = _left;
right = _right;
next = _next;
}
};
*/
class Solution {
private Node getNext(Node root) {
if (root == null) return root;
if (root.left != null) return root.left;
if (root.right != null) return root.right;
return getNext(root.next);
}
public Node connect(Node root) {
if (root == null) return null;
//当左右节点都不会空的时候 连接左右
if (root.left != null && root.right != null) {
root.left.next = root.right;
}
//当左节点不为空,右节点为空时
if (root.left != null && root.right == null) {
root.left.next = getNext(root.next);
}
//当右边不为空时
if (root.right != null) {
root.right.next = getNext(root.next);
}
connect(root.right);
connect(root.left);
return root;
}
}
104. 二叉树的最大深度
题目链接:https://leetcode.cn/problems/maximum-depth-of-binary-tree/
思路一、使用层序遍历看有多少层
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
int depth = 0;
if (root != null) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
depth++;
while (size-- > 0) {
TreeNode treeNode = queue.poll();
if (treeNode.left != null) queue.offer(treeNode.left);
if (treeNode.right != null) queue.offer(treeNode.right);
}
}
}
return depth;
}
}
思路二、使用后续遍历递归
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
if (root == null) return 0;
int depthLeft = maxDepth(root.left);
int depthRight = maxDepth(root.right);
return Math.max(depthLeft, depthRight) + 1;
}
}
111. 二叉树的最小深度
题目链接:https://leetcode.cn/problems/minimum-depth-of-binary-tree/
思路一:使用层序遍历,当treeNode.left == null && treeNode.right == null返回最小的层级
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int minDepth(TreeNode root) {
if (root == null) return 0;
int depth = 0;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
depth++;
while (size -- > 0) {
TreeNode treeNode = queue.poll();
if (treeNode.left == null && treeNode.right == null) {
return depth;
}
if (treeNode.left != null) queue.offer(treeNode.left);
if (treeNode.right != null) queue.offer(treeNode.right);
}
}
return depth;
}
}
思路二:使用后续遍历法
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int minDepth(TreeNode root) {
if (root == null) return 0;
if (root.left != null && root.right == null) {
return 1 + minDepth(root.left);
}
if (root.left == null && root.right != null) {
return 1 + minDepth(root.right);
}
return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
}
}
十一、226. 翻转二叉树
题目链接:https://leetcode.cn/problems/invert-binary-tree/
思路一:深度优先遍历,前序、中序、后序遍历
前序递归
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private void swap(TreeNode root) {
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
}
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
swap(root);
invertTree(root.left);
invertTree(root.right);
return root;
}
}
前序迭代
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private void swap(TreeNode root) {
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
}
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode treeNode = stack.pop();
swap(treeNode);
if (treeNode.right != null) stack.push(treeNode.right);
if (treeNode.left != null) stack.push(treeNode.left);
}
return root;
}
}
中序递归
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private void swap(TreeNode root) {
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
}
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
invertTree(root.left);
swap(root);
invertTree(root.left);
return root;
}
}
后序递归
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private void swap(TreeNode root) {
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
}
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
invertTree(root.left);
invertTree(root.right);
swap(root);
return root;
}
}
后序迭代
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private void swap(TreeNode root) {
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
}
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
TreeNode pre = null;
while (cur != null || !stack.isEmpty()) {
if (cur != null) {
stack.push(cur);
cur = cur.left;
} else {
TreeNode treeNode = stack.peek();
if (treeNode.right == null || treeNode.right == pre) {
swap(treeNode);
stack.pop();
pre = treeNode;
cur = null;
} else {
cur = treeNode.right;
}
}
}
return root;
}
}
思路二、广度优先 层序遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private void swap(TreeNode root) {
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
}
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
while (size-- > 0) {
TreeNode treeNode = queue.poll();
swap(treeNode);
if (treeNode.left != null) queue.offer(treeNode.left);
if (treeNode.right != null) queue.offer(treeNode.right);
}
}
return root;
}
}
十二、101. 对称二叉树
题目链接:https://leetcode.cn/problems/symmetric-tree/
思路一、使用后序遍历(迭代法)
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private boolean isSymmetric(TreeNode leftNode, TreeNode rightNode) {
//终止条件
if (leftNode == null && rightNode == null) return true;
if (leftNode != null && rightNode == null) return false;
if (leftNode == null && rightNode != null) return false;
if (leftNode.val != rightNode.val) return false;
boolean outSide = isSymmetric(leftNode.left, rightNode.right);
if (!outSide) return false;
boolean inSide = isSymmetric(leftNode.right, rightNode.left);
return inSide;
}
public boolean isSymmetric(TreeNode root) {
return isSymmetric(root.left, root.right);
}
}
思路二、层序遍历迭代
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root.left);
queue.offer(root.right);
while (!queue.isEmpty()) {
TreeNode leftNode = queue.poll();
TreeNode rightNode = queue.poll();
if (leftNode == null && rightNode == null) continue;
if (leftNode != null && rightNode == null) return false;
if (leftNode == null && rightNode != null) return false;
if (leftNode.val != rightNode.val) return false;
queue.offer(leftNode.left);
queue.offer(rightNode.right);
queue.offer(leftNode.right);
queue.offer(rightNode.left);
}
return true;
}
}
十二、 100. 相同的树
题目链接:https://leetcode.cn/problems/same-tree/
思路一、后续遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) return true;
if (p == null || q == null) return false;
if (p.val != q.val) return false;
boolean leftSame = isSameTree(p.left, q.left);
if (!leftSame) return false;
boolean rightSame = isSameTree(p.right, q.right);
return rightSame;
}
}
思路二、层序遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(p);
queue.offer(q);
while (!queue.isEmpty()) {
TreeNode pNode = queue.poll();
TreeNode qNode = queue.poll();
if (pNode == null && qNode == null) continue;
if (pNode == null || qNode == null) return false;
if (pNode.val != qNode.val) return false;
queue.offer(pNode.left);
queue.offer(qNode.left);
queue.offer(pNode.right);
queue.offer(qNode.right);
}
return true;
}
}
十三、 572. 另一棵树的子树
题目链接:https://leetcode.cn/problems/subtree-of-another-tree/
思路:后序遍历,左右子树有一个符合条件了就返回
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private boolean isSameTree(TreeNode mainRoot, TreeNode subRoot) {
if (mainRoot == null && subRoot == null) return true;
if (mainRoot == null || subRoot == null) return false;
if (mainRoot.val != subRoot.val) return false;
boolean isLeft = isSameTree(mainRoot.left, subRoot.left);
if (!isLeft) return false;
return isSameTree(mainRoot.right, subRoot.right);
}
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
if (root == null) return false;
if (isSameTree(root, subRoot)) return true;
boolean isLeft = isSubtree(root.left, subRoot);
if (isLeft) return true;
boolean isRight = isSubtree(root.right, subRoot);
return isRight;
}
}