⚡刷题计划day14 二叉树(三)继续,可以点个免费的赞哦~
目录
题目一:101. 对称二叉树
-
对称二叉树
(https://leetcode.cn/problems/symmetric-tree/description/)
判断二叉树对称,其实就是判断二叉树两边内外两侧节点是否相同,如图:
法一:递归法
递归三部曲:
1.确定递归函数的参数和返回值
我们需要比较根节点的两个字树是否对称,之后两边都子节点是否对称,
所以参数自然便是左子树节点和右子树节点。
返回值是boolean类型
2.确定终止条件
首先判断节点为空的情况:
-
左节点为空,右节点不为空,不对称,return false
-
左不为空,右为空,不对称 return false
-
左右都为空,对称,返回true
然后左右节点都不为空,自然便比较节点数值:
-
左右都不为空,比较节点数值,不相同就return false
3.确定单层递归的逻辑
此时才进入单层递归的逻辑,单层递归的逻辑就是处理 左右节点都不为空,且数值相同的情况。
-
比较二叉树外侧是否对称:传入的是左节点的左孩子,右节点的右孩子。
-
比较内侧是否对称,传入左节点的右孩子,右节点的左孩子。
-
如果左右都对称就返回true ,有一侧不对称就返回false 。
AC代码
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
return compare(root.left,root.right);
}
public 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 compareOutside = compare(left.left,right.right);// 左子树:左、 右子树:右
boolean compareInside = compare(left.right,right.left);// 左子树:右、 右子树:左
return compareOutside && compareInside;// 左子树:中、 右子树:中 (逻辑处理
}
}
法二:队列
我们可以通过队列来判断根节点的左子树和右子树的内侧和外侧是否相等,如动画所示:
条件判断和递归的逻辑是一样的。
AC代码
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) {
return false;
}
if (leftNode != null && rightNode == null) {
return false;
}
if (leftNode == null && rightNode == null) {
continue;
}
// 排除了空节点,再排除数值不相同的情况
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;
}
}
题目二:104. 二叉树的最大深度
-
二叉树的最大深度
(https://leetcode.cn/problems/maximum-depth-of-binary-tree/description/)
直接左右递归即可
AC代码:
法一:递归
class Solution {
public int maxDepth(TreeNode root) {
if (root==null) return 0;
int leftDepth = maxDepth(root.left);
int rightDepth = maxDepth(root.right);
return Math.max(leftDepth,rightDepth)+1;
}
}
法二:层序遍历
在二叉树中,一层一层的来遍历二叉树,记录一下遍历的层数就是二叉树的深度,如图所示:
class Solution {
public int maxDepth(TreeNode root) {
if (root==null) return 0;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int depth =0;
while (!queue.isEmpty()){
int len = queue.size();
depth++;
while (len>0){
TreeNode tmpNode = queue.poll();
if(tmpNode.left!=null) queue.offer(tmpNode.left);
if(tmpNode.right!=null) queue.offer(tmpNode.right);
len--;
}
}
return depth;
}
}
同类题目可以做做:559. N 叉树的最大深度
(https://leetcode.cn/problems/maximum-depth-of-n-ary-tree/description/)
题目三:111. 二叉树的最小深度
-
二叉树的最小深度
(https://leetcode.cn/problems/minimum-depth-of-binary-tree/description/)
初看好像和求最大深度差不多,其实还是有区别。
注意一个易错点:
审题,题目中说的是:最小深度是从根节点到最近叶子节点的最短路径上的节点数量。注意是叶子节点,如图。叶子节点即左右孩子都为空的节点。
法一:递归
详细见代码注释
class Solution {
public int minDepth(TreeNode root) {
if (root==null) return 0;
int leftDepth = minDepth(root.left);
int rightDepth = minDepth(root.right);
// 当一个左子树为空,右不为空,这时并不是最低点
if (root.left==null && root.right!=null){
return rightDepth+1;
}
// 当一个右子树为空,左不为空,这时并不是最低点
if (root.left!=null && root.right==null){
return leftDepth+1;
}
return Math.min(leftDepth,rightDepth)+1;
}
}
精简:
class Solution {
public:
int minDepth(TreeNode* root) {
if (root == NULL) return 0;
if (root->left == NULL && root->right != NULL) {
return 1 + minDepth(root->right);
}
if (root->left != NULL && root->right == NULL) {
return 1 + minDepth(root->left);
}
return 1 + min(minDepth(root->left), minDepth(root->right));
}
};
法二:层序遍历
详见注释及代码:
class Solution {
/**
* 迭代法,层序遍历
*/
public int minDepth(TreeNode root) {
if (root == null) {
return 0;
}
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(root);
int depth = 0;
while (!deque.isEmpty()) {
int size = deque.size();
depth++;
for (int i = 0; i < size; i++) {
TreeNode poll = deque.poll();
if (poll.left == null && poll.right == null) {
// 是叶子结点,直接返回depth,因为从上往下遍历,所以该值就是最小值
return depth;
}
if (poll.left != null) {
deque.offer(poll.left);
}
if (poll.right != null) {
deque.offer(poll.right);
}
}
}
return depth;
}
}