代码随想录第十二天|226.翻转二叉树、 101.对称二叉树、104.二叉树的最大深度、111.二叉树的最小深度

文章目录

226.翻转二叉树

题目链接:226. 翻转二叉树 - 力扣(LeetCode)

题目描述:给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

示例 1:

输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]

示例 2:

输入:root = [2,1,3]
输出:[2,3,1]

示例 3:

输入:root = []
输出:[]

提示:

  • 树中节点数目范围在 [0, 100]
  • -100 <= Node.val <= 100

思路

翻转二叉树,其实就是把每个节点的左右孩子交换一下就可以了,因此只要能遍历二叉树,都可以实现二叉树的翻转

解法一、前序遍历递归

c 复制代码
struct TreeNode *invertTree(struct TreeNode *root) {
    if(!root){
        return root;
    }
    //交换左右孩子
    struct TreeNode *node = root->left;
    root->left = root->right;
    root->right = node;
    invertTree(root->left);//递归遍历左子树
    invertTree(root->right);//递归遍历右子树
    return root;
}

解法二、深度优先搜索--迭代

c 复制代码
struct TreeNode* invertTree(struct TreeNode* root) {
    if (!root)
        return NULL;
    // 存储结点的栈
    struct TreeNode** stack =
        (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 100);
    int stackTop = 0;
    // 将根节点入栈
    stack[stackTop++] = root;
    // 若栈中还有元素(进行循环)
    while (stackTop) {
        // 取出栈顶元素
        struct TreeNode* temp = stack[--stackTop];
        // 交换结点的左右孩子
        struct TreeNode* tempNode = temp->right;
        temp->right = temp->left;
        temp->left = tempNode;
        // 若当前结点有左右孩子,将其入栈
        if (temp->left)
            stack[stackTop++] = temp->left;
        if (temp->right)
            stack[stackTop++] = temp->right;
    }
    return root;
}

101.对称二叉树

题目链接:101. 对称二叉树 - 力扣(LeetCode)

题目描述:给你一个二叉树的根节点 root , 检查它是否轴对称。

示例 1:

输入:root = [1,2,2,3,4,4,3]
输出:true

示例 2:

输入:root = [1,2,2,null,3,null,3]
输出:false

思路

判断对称二叉树要比较的不是左右节点

二叉树是否对称,其实是比较根节点的左右子树是不是相互翻转的,所以需要遍历两棵树

本题遍历只能是**"后序遍历"**,因为我们要通过递归函数的返回值来判断两个子树的内侧节点和外侧节点是否相等。

解法一、递归

c 复制代码
bool compare(struct TreeNode* left, struct TreeNode* right) {
    if (!left && !right)
        return true;
    if (left && right && left->val == right->val) {
        bool outside = compare(left->left, right->right);// 左子树:左、 右子树:右
        bool inside = compare(left->right, right->left); // 左子树:右、 右子树:左
        return outside && inside;// 左子树:中、 右子树:中(逻辑处理)
    } else {
        return false;
    }
}

bool isSymmetric(struct TreeNode* root) {
    if (!root)
        return true;
    return compare(root->left, root->right);
}

解法二、迭代

把左右两个子树要比较的元素顺序放进一个容器,然后成对取出来进行比较,使用队列和栈均可

c 复制代码
bool isSymmetric(struct TreeNode *root) {
    if(!root) return true;
    struct TreeNode *stk[1000];
    int top = 0;
    stk[top++] = root->left;
    stk[top++] = root->right;
    while(top){
        struct TreeNode *rightNode = stk[--top];
        struct TreeNode *leftNode = stk[--top];
        if(!rightNode && !leftNode) continue;
        if((!leftNode || !rightNode)||(leftNode->val != rightNode->val)){
            return false;
        }
        stk[top++] = leftNode->left;
        stk[top++] = rightNode->right;
        stk[top++] = leftNode->right;
        stk[top++] = rightNode->left;
    }
    return  true;
}

104.二叉树的最大深度

题目链接:104. 二叉树的最大深度 - 力扣(LeetCode)

题目描述:给定一个二叉树 root ,返回其最大深度。

二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:3

示例 2:

输入:root = [1,null,2]
输出:2

提示:

  • 树中节点的数量在 [0, 104] 区间内。
  • -100 <= Node.val <= 100

解法一、深度优先搜索--递归

c 复制代码
int maxDepth(struct TreeNode *root) {
    if (root == NULL) return 0;
    return fmax(maxDepth(root->left), maxDepth(root->right)) + 1;
}

解法二、广度优先搜索--迭代

通过层次遍历,当遍历到最后一层,层数即二叉树的深度

c 复制代码
#define MAX_SIZE 10000
int maxDepth(struct TreeNode* root) {
    int ans = 0;
    if (!root) {
        return ans;
    }
    struct TreeNode* queue[MAX_SIZE];
    int rear = 0, front = 0;
    queue[rear++] = root;
    while (front != rear) {
        int size = rear - front;
        for (int i = 0; i < size; i++) { // 遍历这一层的所有节点
            struct TreeNode* node = queue[front++]; 
            if (node->left)
                queue[rear++] = node->left;
            if (node->right)
                queue[rear++] = node->right;
        }
        ans++;//层数+1
    }
    return ans;
}

111.二叉树的最小深度

题目链接:111. 二叉树的最小深度 - 力扣(LeetCode)

题目描述:给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

**说明:**叶子节点是指没有子节点的节点。

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:2

示例 2:

输入:root = [2,null,3,null,4,null,5,null,6]
输出:5

提示:

  • 树中节点数的范围在 [0, 105]
  • -1000 <= Node.val <= 1000

解法一、深度优先搜索--递归

对于每一个非叶子节点,我们只需要分别计算其左右子树的最小叶子节点深度。这样就将一个大问题转化为了小问题,可以递归地解决该问题,需要注意的是只有当左右孩子都为空的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点

c 复制代码
int minDepth(struct TreeNode *root) {
    if (root == NULL) {
        return 0;
    }

    if (root->left == NULL && root->right == NULL) {
        return 1;
    }

    int min_depth = INT_MAX;
    if (root->left != NULL) {
        min_depth = fmin(minDepth(root->left), min_depth);
    }
    if (root->right != NULL) {
        min_depth = fmin(minDepth(root->right), min_depth);
    }

    return min_depth + 1;
}

解法二、广度优先搜索--迭代

c 复制代码
#define MAX_SIZE 100000
int minDepth(struct TreeNode* root) {
    int ans = 0;
    if (!root) {
        return ans;
    }
    struct TreeNode* queue[MAX_SIZE];
    int rear = 0, front = 0;
    queue[rear++] = root;
    while (front != rear) {
        int size = rear - front;
        ans++;                           // 层数+1
        for (int i = 0; i < size; i++) { // 遍历这一层的所有节点
            struct TreeNode* node = queue[front++];
            if (node->left)
                queue[rear++] = node->left;
            if (node->right)
                queue[rear++] = node->right;
            // 当左右孩子都为空的时候,说明是最低点的一层了,退出
            if (!node->left && !node->right) {
                return ans;
            }
        }
    }
    return ans;
}
相关推荐
带多刺的玫瑰42 分钟前
Leecode刷题C语言之统计不是特殊数字的数字数量
java·c语言·算法
熬夜学编程的小王1 小时前
【C++篇】深度解析 C++ List 容器:底层设计与实现揭秘
开发语言·数据结构·c++·stl·list
阿史大杯茶1 小时前
AtCoder Beginner Contest 381(ABCDEF 题)视频讲解
数据结构·c++·算法
陌小呆^O^1 小时前
Cmakelist.txt之win-c-udp-server
c语言·开发语言·udp
Chris _data1 小时前
二叉树oj题解析
java·数据结构
时光の尘2 小时前
C语言菜鸟入门·关键字·float以及double的用法
运维·服务器·c语言·开发语言·stm32·单片机·c
-一杯为品-2 小时前
【51单片机】程序实验5&6.独立按键-矩阵按键
c语言·笔记·学习·51单片机·硬件工程
Lenyiin3 小时前
02.06、回文链表
数据结构·leetcode·链表
爪哇学长3 小时前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
爱摸鱼的孔乙己3 小时前
【数据结构】链表(leetcode)
c语言·数据结构·c++·链表·csdn