java的treenode_java中的数组

挑战刷leetcode第7天(二叉树问题递归解决)

哪吒大战二叉树:递归的奇妙冒险

大家好,我是哪吒,今天我要带你们进入一个神奇的世界——二叉树!别担心,虽然我平时喜欢打打杀杀,但这次我们要用递归来解决二叉树的问题。相信我,这比打妖怪有趣多了!

1. 二叉树的最大深度:哪吒的“高度”挑战

首先,我们来看看如何计算二叉树的最大深度。想象一下,二叉树就像一座塔,我们要找到这座塔的最高点。

Java版

public int maxDepth(TreeNode root) {
    if (root == null) {
        return 0;
    }
    return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}

C++版

int maxDepth(TreeNode* root) {
    if (root == nullptr) {
        return 0;
    }
    return max(maxDepth(root->left), maxDepth(root->right)) + 1;
}

哪吒解说:

  • 如果树是空的(root == null),那高度当然是0啦,就像一座空塔。
  • 否则,我们分别计算左子树和右子树的高度,然后取最大值,再加上当前节点的高度1。

思考题:

如果二叉树是一个链表(所有节点都只有左子节点或右子节点),最大深度会是多少?

2. 翻转二叉树:哪吒的“镜像”大法

接下来,我们要翻转二叉树。这就像照镜子一样,左右互换。

Java版

public TreeNode invertTree(TreeNode root) {
    if (root == null) {
        return root;
    }
    TreeNode left = root.left;
    root.left = root.right;
    root.right = left;

    invertTree(root.left);
    invertTree(root.right);
    return root;
}

C++版

TreeNode* invertTree(TreeNode* root) {
    if (root == nullptr) {
        return root;
    }
    TreeNode* left = root->left;
    root->left = root->right;
    root->right = left;

    invertTree(root->left);
    invertTree(root->right);
    return root;
}

哪吒解说:

  • 如果树是空的,直接返回。
  • 否则,我们先交换当前节点的左右子节点,然后递归地对左右子树进行同样的操作。

思考题:

如果二叉树是一个满二叉树(所有非叶子节点都有两个子节点),翻转后会变成什么样子?

3. 对称二叉树:哪吒的“对称”考验

现在,我们要判断一棵二叉树是否对称。这就像看一幅画,左右两边是否完全一样。

Java版

public boolean isSymmetric(TreeNode root) {
    return isSymmetric(root.left, root.right);
}

public boolean isSymmetric(TreeNode node1, TreeNode node2) {
    if (node1 == null && node2 == null) {
        return true;
    }
    if (node1 == null || node2 == null) {
        return false;
    }

    if (node1.val != node2.val) {
        return false;
    }
    return isSymmetric(node1.left, node2.right) && isSymmetric(node1.right, node2.left);
}

C++版

bool isSymmetric(TreeNode* root) {
    if (root == nullptr) {
        return true;
    }
    return isSymmetric(root->left, root->right);
}

bool isSymmetric(TreeNode* node1, TreeNode* node2) {
    if (node1 == nullptr && node2 == nullptr) {
        return true;
    }

    if (node1 == nullptr || node2 == nullptr) {
        return false;
    }

    if (node1->val != node2->val) {
        return false;
    }
    return isSymmetric(node1->left, node2->right) &&
           isSymmetric(node1->right, node2->left);
}

哪吒解说:

  • 如果两个节点都为空,那它们是对称的。
  • 如果只有一个节点为空,那就不对称。
  • 如果两个节点的值不相等,那也不对称。
  • 最后,递归地检查左子树的左节点和右子树的右节点,以及左子树的右节点和右子树的左节点。

思考题:

如果二叉树是一个完全二叉树(除了最后一层,其他层都是满的,并且最后一层的节点都靠左),它是否一定是对称的?

4. 二叉树的最近公共祖先:哪吒的“寻亲”之旅

最后,我们要找到二叉树中两个节点的最近公共祖先。这就像在家族树中找到一个共同的祖先。

Java版

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    if (root == null || root == q || root == p) {
        return root;
    }

    TreeNode left = lowestCommonAncestor(root.left, p, q);
    TreeNode right = lowestCommonAncestor(root.right, p, q);

    if (left == null) {
        return right;
    }
    if (right == null) {
        return left;
    }
    return root;
}

C++版

TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    if (root == nullptr || root == q || root == p) {
        return root;
    }

    TreeNode* left = lowestCommonAncestor(root->left, p, q);
    TreeNode* right = lowestCommonAncestor(root->right, p, q);

    if (left == nullptr) {
        return right;
    }
    if (right == nullptr) {
        return left;
    }
    return root;
}

哪吒解说:

  • 如果当前节点是空,或者就是我们要找的节点之一,直接返回当前节点。
  • 否则,我们分别在左子树和右子树中寻找这两个节点。
  • 如果左子树中没有找到,那最近公共祖先就在右子树中。
  • 如果右子树中没有找到,那最近公共祖先就在左子树中。
  • 如果两个子树都找到了,那当前节点就是最近公共祖先。

思考题:

如果二叉树是一个二叉搜索树(BST),最近公共祖先的查找会有什么不同?

结语:坚持的意义

通过这次冒险,我们不仅学会了如何用递归解决二叉树的问题,还发现了递归的美妙之处。递归就像哪吒的“三头六臂”,虽然看起来复杂,但一旦掌握,就能轻松应对各种挑战。

坚持的意义在于,每一次的递归调用,都是对问题的一次分解和简化。只要我们坚持不懈,最终总能找到问题的答案。就像哪吒一样,无论面对多么强大的敌人,只要坚持战斗,最终总能取得胜利。

希望你们喜欢这次冒险,下次再见!

原文链接:,转发请注明来源!