目录
一.二叉树的层序遍历
1.T102:二叉树的层序遍历
T: 给你二叉树的根节点 root,返回其节点值的 层序遍历 (即逐层地,从左到右访问所有节点)
提示:
-
树中节点数目在范围 [0, 2000] 内
-
-1000 <= Node.val <= 1000
S:
法1、使用队列
C++:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if (root == nullptr) return res;
queue<TreeNode*> que;
// que.add(root);
que.push(root);
while (!que.empty()) {
int size = que.size();
vector<int> vec;//每轮都是一个新的vector
for (int i = 0; i < size; ++i) {
TreeNode* cur = que.front();
que.pop();
vec.push_back(cur->val);
if (cur->left) que.push(cur->left);
if (cur->right) que.push(cur->right);
}
res.push_back(vec);
}
return res;
}
Java:
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new LinkedList<>();
if (root == null) return res;
Deque<TreeNode> quque = new LinkedList<>();
quque.add(root);
while (!quque.isEmpty()) {
int size = quque.size();
List<Integer> level = new LinkedList<>();
for (int i = 0; i < size; ++i) {
TreeNode cur = quque.poll();
level.add(cur.val);
if (cur.left != null) quque.offer(cur.left);
if (cur.right != null) quque.offer(cur.right);
}
res.add(level);
}
return res;
}
法2、递归
C++:
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
int depth = 0;
order(root, res, depth);
return res;
}
private:
// void order(TreeNode* node, vector<vector<int>> result, int depth) {//犯错
void order(TreeNode* node, vector<vector<int>>& result, int depth) {
if (!node) return;
if (depth == result.size()) result.push_back(vector<int>());//!=说明前面已经处理过同层节点
result[depth].push_back(node->val);//肯定是当前层
order(node->left, result, depth + 1);
order(node->right, result, depth + 1);
}
Java:
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if (root == null) return res;
int depth = 0;
order(root, res, depth);
return res;
}
private void order(TreeNode node, List<List<Integer>> result, int depth) {
if (node == null) return;
// if (depth == result.size()) result.add(new LinkedList<>());//都可以
if (depth == result.size()) result.add(new LinkedList<Integer>());
result.get(depth).add(node.val);
order(node.left, result, depth + 1);
order(node.right, result, depth + 1);
}
2.T107:二叉树的层序遍历Ⅱ
T:给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
S:
C++:直接在上一题的基础上进行一维子数组的反转就行了
vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int>> res;
if (!root) return res;
queue<TreeNode*> que;
que.push(root);
while (!que.empty()) {
int size = que.size();
vector<int> vec;
TreeNode* node = nullptr;
for (int i = 0; i < size; ++i) {
node = que.front();
que.pop();
vec.push_back(node->val);
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
res.push_back(vec);
}
reverse(res.begin(), res.end());//加上这一行就行
return res;
}
Java:反转可以自己实现,也可以直接套用工具类的方法
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if (root == null) return res;
Deque<TreeNode> queue = new ArrayDeque<>();
queue.add(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> list = new LinkedList<>();
for (int i = 0; i < size; ++i) {
TreeNode node = queue.poll();
list.add(node.val);
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}
res.add(list);
}
// Collections.reverse(res);
// return res;
//自己实现反转(new了一个新的List)
List<List<Integer>> result = new ArrayList<>();
for (int i = res.size() - 1; i >= 0; --i) {
result.add(res.get(i));
}
return result;
}
3.T199:二叉树的右视图
T: 给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
提示:
-
二叉树的节点个数的范围是 [0,100]
-
-100 <= Node.val <= 100
S:
层序遍历的时候,判断是否遍历到单层的最后面的元素,如果是,就放进result数组中,随后返回result就行了
C++:self:自己按照前几题的思路写的,但实际上本题不需要额外再用一个临时vector变量
vector<int> rightSideView(TreeNode* root) {
vector<int> res;
queue<TreeNode*> que;
if (root != nullptr) que.push(root);
while (!que.empty()) {
int size = que.size();
// vector<int> vec;//self
for (int i = 0; i < size; ++i) {
TreeNode* node = que.front();
que.pop();
// vec.push_back(node->val);//self
if (i == (size - 1)) res.push_back(node->val);//Carl
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
// res.push_back(vec[vec.size() - 1]);//self
}
return res;
}
Java:
public List<Integer> rightSideView(TreeNode root) {
List<Integer> res = new LinkedList<>();
if (root == null) return res;
Deque<TreeNode> queue = new ArrayDeque<>();
queue.addLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; ++i) {
TreeNode node = queue.pollFirst();
if (i == size - 1) res.add(node.val);
if (node.left != null) queue.addLast(node.left);
if (node.right != null) queue.addLast(node.right);
}
}
return res;
}
4.T637:二叉树的层平均值
T: 给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。
提示:
-
树中节点数量在 [1, 104] 范围内
-
-231 <= Node.val <= 231 - 1
S:题目已经明示了要用double,那没什么好说的了
C++:
vector<double> averageOfLevels(TreeNode* root) {
vector<double> res;
if (!root) return res;
queue<TreeNode*> que;
que.push(root);
while (!que.empty()) {
int size = que.size();
double sum = 0;
for (int i = 0; i < size; ++i) {
TreeNode* node = que.front();
que.pop();
sum += node->val;
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
res.push_back(sum / size);
}
return res;
}
Java:
public List<Double> averageOfLevels(TreeNode root) {
List<Double> res = new LinkedList<>();
if (root == null) return res;
Deque<TreeNode> queue = new LinkedList<>();
queue.addLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
double sum = 0;
for (int i = 0; i < size; ++i) {
TreeNode node = queue.pollFirst();
sum += node.val;
if (node.left != null) queue.addLast(node.left);
if (node.right != null) queue.addLast(node.right);
}
res.add(sum / size);
}
return res;
}
5.T429:N叉树的层序遍历
-
树的高度不会超过 1000
-
树的节点总数在 [0, 10^4] 之间
vector<vector<int>> levelOrder(Node* root) {
vector<vector<int>> res;
if (!root) return res;
queue<Node*> que;
que.push(root);
while (!que.empty()) {
int size = que.size();
vector<int> vec;
for (int i = 0; i < size; ++i) {
Node* node = que.front();
que.pop();
vec.push_back(node->val);
// if (!node->children || node->children.size() == 0) continue;
// if (node->children == nullptr || node->children.size() == 0) continue;//invalid operands to binary expression
// if (node->children == NULL || node->children.size() == 0) continue;//comparison between NULL and non-pointer
if (node->children.size() == 0) continue;
for (int j = 0; j < node->children.size(); ++j) {
if (node->children[j]) {
que.push(node->children[j]);
}
}
}
res.push_back(vec);
}
return res;
}
Java:
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> res = new LinkedList<>();
if (root == null) return res;
Deque<Node> queue = new LinkedList<>();
queue.addLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> list = new LinkedList<>();
for (int i = 0; i < size; ++i) {
Node node = queue.pollFirst();
list.add(node.val);
if (node.children != null && node.children.size() >= 0) {//设置反向然后continue也行
for (Node child : node.children) {
queue.addLast(child);
}
}
}
res.add(list);
}
return res;
}
6.T515:在每个树行中找最大值
T515: 给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。
提示:
-
二叉树的节点个数的范围是 [0,104]
-
-231 <= Node.val <= 231 - 1
S:找出最大值的方法有很多,可以自己实现,也可以借助各种语言自带的工具类方法
C++:
vector<int> largestValues(TreeNode* root) {
vector<int> res;
if (!root) return res;
queue<TreeNode*> que;
que.push(root);
while (!que.empty()) {
int size = que.size();
int maxVal = INT_MIN;//
for (int i = 0; i < size; ++i) {
TreeNode* node = que.front();
que.pop();
maxVal = node->val > maxVal ? node->val : maxVal;//
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
res.push_back(maxVal);
}
return res;
}
Java:
public List<Integer> largestValues(TreeNode root) {
List<Integer> res = new LinkedList<>();
if (root == null) return res;
Deque<TreeNode> queue = new LinkedList<>();
queue.addLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
// List<Integert> candidates = new ArrayList<>();
int maxVal = Integer.MIN_VALUE;
for (int i = 0; i < size; ++i) {
TreeNode node = queue.pollFirst();
// candidates.add(node.val);
maxVal = Math.max(maxVal, node.val);
if (node.left != null) queue.addLast(node.left);
if (node.right != null) queue.addLast(node.right);
}
// res.add(Math.max(candidates))//without this usage
res.add(maxVal);
}
return res;
}
7.T116:填充每个节点的下一个右侧节点指针
T116:给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL。
提示:
-
树中节点的数量在 [0, 212 - 1] 范围内
-
-1000 <= node.val <= 1000
进阶:
-
你只能使用常量级额外空间。
-
使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
S:
Node* connect(Node* root) {
queue<Node*> que;
if (root) que.push(root);
while (!que.empty()) {
int size = que.size();
Node* preNode;
Node* curNode;
for (int i = 0; i < size; ++i) {
if (i == 0) {
preNode = que.front();// 取出一层的头结点
que.pop();
curNode = preNode;
} else {
curNode = que.front();
que.pop();
preNode->next = curNode;// 本层前一个节点的next指向本节点
// preNode = preNode->next;//
preNode = curNode;//和上一行哪种都可以
}
if (curNode->left) que.push(curNode->left);
if (curNode->right) que.push(curNode->right);
}
preNode->next = nullptr;//本层最后一个节点指向空
}
return root;
}
Java:
public Node connect(Node root) {
Deque<Node> queue = new LinkedList<>();
if (root != null) queue.addLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
Node preNode = null;
Node curNode = null;
for (int i = 0; i < size; ++i) {
if (i == 0) {
preNode = queue.pollFirst();
curNode = preNode;
} else {
curNode = queue.pollFirst();
preNode.next = curNode;
preNode = curNode;
}
if (curNode.left != null) queue.addLast(curNode.left);
if (curNode.right != null) queue.addLast(curNode.right);
}
preNode.next = null;
}
return root;
}
8.T117:填充每个节点的下一个右侧节点指针Ⅱ
T117:给定一个二叉树
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL。
进阶:
-
你只能使用常量级额外空间。
-
使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
提示:
- 树中的节点数小于
6000
-100 <= node.val <= 100
S:和上一题的差别只是在于此题不是完美二叉树,思路和代码完全一样(略)
9.T104:二叉树的最大深度
T104:给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
S:一样的套路,每迭代一层就层数+1,最后得出的结果就是最大层数,也就是二叉树的最大深度
C++:
int maxDepth(TreeNode* root) {
// if (!root) return -1;
if (!root) return 0;
queue<TreeNode*> que;
que.push(root);
int maxDepth = 0;
while (!que.empty()) {
int size = que.size();
++maxDepth;
for (int i = 0; i < size; ++i) {
TreeNode* node = que.front();
que.pop();
// ++maxDepth;
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
}
return maxDepth;
}
Java:
public int maxDepth(TreeNode root) {
if (root == null) return 0;
Deque<TreeNode> queue = new LinkedList<>();
queue.addLast(root);
int maxDepth = 0;
while (!queue.isEmpty()) {
int size = queue.size();
++maxDepth;
for (int i = 0; i < size; ++i) {
TreeNode node = queue.pollFirst();
if (node.left != null) queue.addLast(node.left);
if (node.right != null) queue.addLast(node.right);
}
}
return maxDepth;
}
10.T111:二叉树的最小深度
-
树中节点数的范围在 [0, 105] 内
-
-1000 <= Node.val <= 1000
本题依旧可以使用层序遍历的方式来解决,思路是一样的。
需要注意的是,只有当左右孩子都为空的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点,而且一定是第一次(层)遇到的时候是。
int minDepth(TreeNode* root) {
if (!root) return 0;
// int minDepth = INT_MAX;
int depth = 0;
queue<TreeNode*> que;
que.push(root);
while (!que.empty()) {
int size = que.size();
++depth;
for (int i = 0; i < size; ++i) {
TreeNode* node = que.front();
que.pop();
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
if (!node->left && !node->right) {// 当左右孩子都为空的时候,说明是最低点的一层了,退出
// minDepth = depth;
// break;
return depth;//只要第一次(层)遇到,就绝对是最小深度
// minDepth = depth;
// return minDepth;
}
}
// minDepth = depth < minDepth ? depth : minDepth;//完全不需要
}
// return minDepth;
return depth;//如果刚好是满二叉树,那就返回最后的层数即可
}
Java:
public int minDepth(TreeNode root) {
if (root == null) return 0;
Deque<TreeNode> queue = new LinkedList<>();
queue.addLast(root);
int depth = 0;
while (!queue.isEmpty()) {
int size = queue.size();
++depth;
for (int i = 0; i < size; ++i) {
TreeNode node = queue.pollFirst();
if (node.left != null) queue.addLast(node.left);
if (node.right != null) queue.addLast(node.right);
if (node.left == null && node.right == null) return depth;
}
}
return depth;
}
二.T226:翻转二叉树
T226: 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
提示:
-
树中节点数目范围在 [0, 100] 内
-
-100 <= Node.val <= 100
S:在遍历的基础上,加上当前节点的左右子节点交换即可
代码实现
法1、递归(深度优先遍历)
C++:
//【前序】
public:
TreeNode* invertTree(TreeNode* root) {
// if (!root) return root;
preOrderTraversal(root);
return root;
}
private:
void preOrderTraversal(TreeNode* node) {
if (!node) return;
swap(node->left, node->right);//可以空空交换
preOrderTraversal(node->left);
preOrderTraversal(node->right);
}
//【(伪)中序】
public:
TreeNode* invertTree(TreeNode* root) {
// if (!root) return root;
inOrderTraversal(root);
return root;
}
private:
void inOrderTraversal(TreeNode* node) {
if (!node) return;
inOrderTraversal(node->left);
swap(node->left, node->right);
inOrderTraversal(node->left);//注意此处,已经不是原来的中序遍历递归了
}
//后序略
Java:与C++的代码也没什么区别,就以上面略的后序为例
public TreeNode invertTree(TreeNode root) {
postOrder(root);
return root;
}
private void postOrder(TreeNode node) {
if (node == null) return;
postOrder(node.left);
postOrder(node.right);
swapChild(node);
// swapNode(node.left, node.right);//无效(原因见思考part)
}
private void swapChild(TreeNode node) {
TreeNode temp = node.left;
node.left = node.right;
node.right = temp;
}
private void swapNode(TreeNode node1, TreeNode node2) {
TreeNode temp = node1;
node1 = node2;
node2 = temp;
}
法2、迭代(深度优先遍历)
C++:
//【前序】
TreeNode* invertTree(TreeNode* root) {
// if (!root) return root;//either
stack<TreeNode*> st;
if (root) st.push(root);//or
while (!st.empty()) {
TreeNode* node = st.top();
st.pop();
swap(node->left, node->right);
if (node->right) st.push(node->right);
if (node->left) st.push(node->left);
}
return root;
}
法3、统一迭代(深度优先遍历)
C++:
//【前序】
TreeNode* invertTree(TreeNode* root) {
if (!root) return root;
stack<TreeNode*> st;
st.push(root);
while (!st.empty()) {
TreeNode* node = st.top();
if (node) {
st.pop();
if (node->right) st.push(node->right);
if (node->left) st.push(node->left);
st.push(node);
st.push(nullptr);
} else {
st.pop();
node = st.top();
st.pop();
swap(node->left, node->right);
}
}
return root;
}
//【中序】
TreeNode* invertTree(TreeNode* root) {
if (!root) return root;
stack<TreeNode*> st;
st.push(root);
while (!st.empty()) {
TreeNode* node = st.top();
if (node) {
st.pop();
if (node->right) st.push(node->right);
st.push(node);
st.push(nullptr);
if (node->left) st.push(node->left);
} else {
st.pop();
node = st.top();
st.pop();
swap(node->left, node->right);
}
}
return root;
}
Java:
//【后序】
public TreeNode invertTree(TreeNode root) {
if (root == null) return root;
Deque<TreeNode> queue = new LinkedList<>();
queue.offerFirst(root);
while (!queue.isEmpty()) {
TreeNode node = queue.getFirst();
if (node != null) {
queue.removeFirst();
queue.addFirst(node);
queue.addFirst(null);
if (node.right != null) queue.push(node.right);
if (node.left != null) queue.push(node.left);
} else {
queue.pollFirst();
node = queue.peekFirst();
queue.pop();
swapChild(node);
}
}
return root;
}
private void swapChild(TreeNode node) {
TreeNode temp = node.left;
node.left = node.right;
node.right = temp;
}
法4、广度优先遍历【迭代】
C++:
TreeNode* invertTree(TreeNode* root) {
if (!root) return root;
queue<TreeNode*> que;
que.push(root);
while (!que.empty()) {
int size = que.size();
for (int i = 0; i < size; ++i) {
TreeNode* node = que.front();
que.pop();
swap(node->left, node->right);
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
}
return root;
}
Java:
public TreeNode invertTree(TreeNode root) {
if (root == null) return root;
Deque<TreeNode> queue = new LinkedList<>();
queue.addLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; ++i) {
TreeNode node = queue.pollFirst();
// swapNode(node.left, node.right);//无效(搞清楚原因!!!)
swapChild(node);
if (node.left != null) queue.addLast(node.left);
if (node.right != null) queue.addLast(node.right);
}
}
return root;
}
private void swapChild(TreeNode node) {
TreeNode temp = node.left;
node.left = node.right;
node.right = temp;
}
法5、广度优先遍历【递归】
这个方法可以用是可以用,但毕竟不是真的在遍历,所以vector的存在可能有点多余
C++:
TreeNode* invertTree(TreeNode* root) {
if (!root) return root;
vector<vector<int>> vec;
int depth = 0;
orderByLevel(root, vec, depth);
return root;
}
void orderByLevel(TreeNode* node, vector<vector<int>>& vec, int depth) {
if (!node) return;
if (depth == vec.size()) vec.push_back(vector<int>());
vec[depth].push_back(node->val);
swap(node->left, node->right);
orderByLevel(node->left, vec, depth + 1);
orderByLevel(node->right, vec, depth + 1);
}
思考
Q:写的时候发现一个问题,那就是交换左右子节点必须传入节点本体,传入左右子节点则无法交换?(见递归遍历写法中Java部分)
A:思考之后得出结论:如果传入左右子节点,那么交换的只是左右子节点指针的指向,而对它们的父节点来说,其左右子节点(的内存空间)并没有交换
三.T101:对称二叉树
T101:给你一个二叉树的根节点 root , 检查它是否轴对称。
提示:
-
树中节点数目在范围 [1, 1000] 内
-
-100 <= Node.val <= 100
进阶:你可以运用递归和迭代两种方法解决这个问题吗?
S:本题无论是递归还是迭代,关键在于一定要把空值(子节点)与对称的所有情况考虑周全!
代码实现
法1、递归
C++:
bool isSymmetric(TreeNode* root) {
if (!root) return true;
return compare(root->left, root->right);
}
bool compare(TreeNode* left, TreeNode* right) {
if (!left && right) return false;
else if (left && !right) return false;
else if (!left && !right) return true;
else if (left->val != right->val) return false;
else {
return compare(left->left, right->right) && compare(left->right, right->left);
}
}
Java:
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
return compare(root.left, root.right);
}
private boolean compare(TreeNode left, TreeNode right) {
if (left == null && right == null) return true;
else if (left != null && right == null) return false;
else if (left == null && right != null) return false;
else if (left.val != right.val) return false;
else {
return compare(left.left, right.right) && compare(left.right, right.left);
}
}
法2、层序(队列)
C++:
bool isSymmetric(TreeNode* root) {
if (!root) return true;
queue<TreeNode*> que;
que.push(root->left);
que.push(root->right);
while (!que.empty()) {
TreeNode* left = que.front();
que.pop();
TreeNode* right = que.front();
que.pop();
if (!left && !right) {
// return true;//别傻!
continue;
}
// 左右一个节点不为空,或者都不为空但数值不相同,返回false
if (!left || !right || left->val != right->val) {
return false;
}
que.push(left->left);
que.push(right->right);
que.push(left->right);
que.push(right->left);
}
return true;
}
Java:
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
Deque<TreeNode> que = new LinkedList<>();
que.offerLast(root.left);
que.addLast(root.right);
while (!que.isEmpty()) {
TreeNode left = que.pop();
TreeNode right = que.pollFirst();
if (left == null && right == null) {
continue;
}
if (left == null || right == null || left.val != right.val) {
return false;
}
que.addLast(left.left);
que.addLast(right.right);
que.addLast(left.right);
que.addLast(right.left);
}
return true;
}
法3、层序(栈)
跟队列几乎一模一样
C++:
bool isSymmetric(TreeNode* root) {
if (!root) return true;
stack<TreeNode*> st;
st.push(root->right);
st.push(root->left);
while (!st.empty()) {
TreeNode* left = st.top();
st.pop();
TreeNode* right = st.top();
st.pop();
if (!left && !right) continue;
if (!left || !right || left->val != right->val) {
return false;
}
st.push(left->left);
st.push(right->right);
st.push(left->right);
st.push(right->left);
}
return true;
}
Java:
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
Deque<TreeNode> stack = new LinkedList<>();
stack.push(root.right);
stack.push(root.left);
while (!stack.isEmpty()) {
TreeNode left = stack.pop();
TreeNode right = stack.pop();
if (left == null && right == null) continue;
if (left == null || right == null || left.val != right.val)
return false;
stack.push(right.right);
stack.push(left.left);
stack.push(right.left);
stack.push(left.right);
}
return true;
}