101、对称二叉树
基本思想:
比较的是两个子树的里侧和外侧
遍历顺序为后序遍历,
因为要通过递归函数的返回值来判断两个子树的内侧节点和外侧节点是否相等
一个树的遍历顺序是左右中,一个树的遍历顺序是右左中
具体实现:
1.确定递归函数的参数和返回值
参数:左子树节点和右子树节点
返回值:布尔类型
2.确定终止条件
- 左节点为空,右节点不为空,不对称,return false
- 左节点不为空,右节点为空,不对称,return false
- 左右都为空,对称,返回true
- 左右节点都不为空,比较节点数值,不相同就return false
3.确定单层递归逻辑
单层递归的逻辑就是处理左右节点都不为空,且数值相等的情况
- 比较二叉树的外侧是否对称:传入的是左节点的左孩子,右节点的右孩子
- 比较内侧是否对称,传入左节点的右孩子,右节点的左孩子
- 如果左右都对称就返回true,有一侧不对称就返回false
代码:
class Solution { public boolean isSymmetric(TreeNode root) { return compare(root.left,root.right); } private boolean compare(TreeNode left, TreeNode right){ if (left == null && right != null) return false; if (left != null && right == null) return false; if (left == null && right == null) return true; if (left.val != right.val) return false; boolean compareOutsize = compare(left.left, right.right); boolean compareInside = compare(left.right, right.left); return compareInside && compareOutsize; } }
双端队列
class Solution { public boolean isSymmetric(TreeNode root) { Deque<TreeNode> deque = new LinkedList<>(); deque.offerFirst(root.left); deque.offerLast(root.right); while (!deque.isEmpty()){ TreeNode leftNode = deque.pollFirst(); TreeNode rightNode = deque.pollLast(); if (leftNode == null && rightNode == null) continue; if (leftNode == null || rightNode == null || leftNode.val != rightNode.val) return false; deque.offerFirst(leftNode.left); deque.offerFirst(leftNode.right); deque.offerLast(rightNode.right); deque.offerLast(rightNode.left); } return true; } }
普通队列(迭代法)
class Solution { public boolean isSymmetric(TreeNode root) { Queue<TreeNode> deque = new LinkedList<>(); deque.offer(root.left); deque.offer(root.right); while (!deque.isEmpty()){ TreeNode leftNode = deque.poll(); TreeNode rightNode = deque.poll(); if (leftNode == null && rightNode == null) continue; if (leftNode == null || rightNode == null || leftNode.val != rightNode.val) return false; // 这里顺序与使用Deque不同 deque.offer(leftNode.left); deque.offer(rightNode.right); deque.offer(leftNode.right); deque.offer(rightNode.left); } return true; } }
100、相同的树
递归
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; return isSameTree(p.left,q.left) && isSameTree(p.right,q.right); } }
双端队列
class Solution { public boolean isSameTree(TreeNode p, TreeNode q) { Deque<TreeNode> deque = new LinkedList<>(); deque.offerFirst(p); deque.offerLast(q); while (!deque.isEmpty()){ p = deque.pollFirst(); q = deque.pollLast(); if (p == null && q == null) continue; if (p == null || q == null || p.val != q.val) return false; deque.offerFirst(p.left); deque.offerFirst(q.right); deque.offerLast(p.left); deque.offerLast(q.right); } return true; } }
迭代
class Solution { public boolean isSameTree(TreeNode p, TreeNode q) { Deque<TreeNode> deque = new LinkedList<>(); deque.offer(p); deque.offer(q); while (!deque.isEmpty()){ p = deque.poll(); q = deque.poll(); if (p == null && q == null) continue; if (p == null || q == null || p.val != q.val) return false; deque.offer(p.left); deque.offer(q.left); deque.offer(p.right); deque.offer(q.right); } return true; } }
572、另一棵树的子树
代码:
class Solution { public boolean isSubtree(TreeNode s, TreeNode t) { if (t == null) return true; // t 为 null 一定都是 true if (s == null) return false; // 这里 t 一定不为 null, 只要 s 为 null,肯定是 false return isSubtree(s.left, t) || isSubtree(s.right, t) || isSameTree(s,t); } /** * 判断两棵树是否相同 */ public boolean isSameTree(TreeNode s, TreeNode t){ if (s == null && t == null) return true; if (s == null || t == null) return false; if (s.val != t.val) return false; return isSameTree(s.left, t.left) && isSameTree(s.right, t.right); } }