Java数据结构学习DAY5——二叉树(三)
1、 基础面试题(力扣练习)
- 二叉树的前序遍历。
- 二叉树中序遍历 。
- 二叉树的后序遍历 。
- 检查两颗树是否相同。
- 另一颗树的子树。
- 二叉树最大深度。
- 判断一颗二叉树是否是平衡二叉树。
- 对称二叉树。
1.1 二叉树的前序遍历
-
问题描述:144. 二叉树的前序遍历,给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
-
力扣代码实现(Java)
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null) {
return result;
//不要 return null
}
//先访问根节点,此处的 “访问” 不是打印,而是插入 result 末尾
result.add(root.val);
//递归处理左子树,此时会得到一个左子树的遍历结果的 list ,这个结果也要加到 result 中
result.addAll(preorderTraversal(root.left));
//递归处理右子树
result.addAll(preorderTraversal(root.right));
return result;
}
}
- 结果
1.2 二叉树中序遍历
- 问题描述:94. 二叉树的中序遍历,给定一个二叉树的根节点 root ,返回它的 中序 遍历。
- 力扣代码实现(Java)
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null) {
return result;
}
//递归处理左子树
result.addAll(inorderTraversal(root.left));
//访问根节点
result.add(root.val);
//递归处理右子树
result.addAll(inorderTraversal(root.right));
return result;
}
}
- 结果
1.3二叉树的后序遍历
- 题目描述:145. 二叉树的后序遍历,给定一个二叉树,返回它的 后序 遍历。
- 力扣代码实现
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
if ( root == null) {
return result;
}
//递归处理左子树
result.addAll(postorderTraversal(root.left));
//递归处理右子树
result.addAll(postorderTraversal(root.right));
//访问根节点
result.add(root.val);
return result;
}
}
- 结果
1.4检查两颗树是否相同。
- 题目描述:100. 相同的树,给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的 - 解决思路
判定两个树是否相同,先比较两个根节点是否相同;
若根节点的值相同,再递归比较两个左子树是否相同,再递归比较两个右子树是否相同;
如三个条件同时具备,则认为两个树相同。 - 力扣代码实现
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
}
// if ((p == null && q != null)||(p != null && q == null)) {
// return false;
// }
if (p == null || q == null) {
//进入这个条件意味着,一定是 p 和 q 其中一个为空,一个不为空
return false;
}
//都不为空,先判断根节点是否值相同
if (p.val != q.val) {
return false;
}
//根节点相同,再去比较左右子树
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
}
- 结果
1.5 另一颗树的子树。
- 题目描述:572. 另一个树的子树,给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。
- 解题思路
判定子树是判定两个树相同的延伸,遍历 s ,看 s 上的某个节点对应的子树,是否和 t 这个树是相等的。
遍历 s 看当前节点对应的子树是否和 t 相等;
若不相等,再 递归判定 s 的左子树是否包含 t | | 递归判定 s 的右子树是否包含 t - 力扣代码实现
class Solution {
//判定两棵二叉树是否相同
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
}
// if ((p == null && q != null)||(p != null && q == null)) {
// return false;
// }
if (p == null || q == null) {
//进入这个条件意味着,一定是 p 和 q 其中一个为空,一个不为空
return false;
}
//都不为空,先判断根节点是否值相同
if (p.val != q.val) {
return false;
}
//根节点相同,再去比较左右子树
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
//判定是一个树是否是另一个树的子树
public boolean isSubtree(TreeNode s, TreeNode t) {
if (s == null) {
return false;
}
boolean ret = isSameTree(s,t);
if(ret) {
return ret;
}
return isSubtree(s.left, t) || isSubtree(s.right, t);
}
}
- 结果
1.6 二叉树最大深度
- 题目描述:104. 二叉树的最大深度,给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
- 力扣代码实现
class Solution {
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
int leftHeight = maxDepth(root.left);
int rightHeight = maxDepth(root.right);
return 1 + (leftHeight > rightHeight ? leftHeight : rightHeight);
}
}
- 结果
1.7 判断是否是平衡二叉树
-
力扣题目:110. 平衡二叉树,给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点的左右两个子树的高度差的绝对值不超过 1 。
-
解题思路
判定当前树是否平衡 = 判断当前树左右子树高度差是否是小于1 -
力扣代码
class Solution {
public boolean isBalanced(TreeNode root) {
if (root == null) {
return true;
}
//针对当前节点计算左右子树的高度
int leftLength = getHeight(root.left);
int rightLenght = getHeight(root.right);
if ((leftLength - rightLenght > 1) ||(leftLength - rightLenght < -1)) {
return false;
}
return isBalanced(root.left) && isBalanced(root.right);
}
private int getHeight(TreeNode root) {
if (root ==null){
return 0;
}
int leftHight = getHeight(root.left);
int rightHight = getHeight(root.right);
return 1 + (leftHight > rightHight ? leftHight:rightHight);
}
}
- 结果
1.8 对称二叉树
- 题目表述:101. 对称二叉树,给定一个二叉树,检查它是否是镜像对称的。
- 解题思路
判断一个树是否对称,主要是看左右子树是否是镜像关系;
判断两个树 s 和 t 的镜像关系 = s 和 t 的根节点值一样 && s.left 和 t.right 是否是镜像关系 && s.right 和 t.left 是否是镜像关系 - 力扣代码实现
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) {
return true;
}
return isMirror(root.left, root.right);
}
private boolean isMirror(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 isMirror(s.left, t.right) && isMirror(s.right, t.left);
}
}
- 结果