【代码随想录】【算法训练营】【第16天】 [104]二叉树的最大深度 [111]二叉树的最小深度 [222]完全二叉树的节点个数

前言

思路及算法思维,指路 代码随想录
题目来自 LeetCode

day 16,周四,再坚持一下吧~

题目详情

[104] 二叉树的最大深度

题目描述

104 二叉树的最大深度
104 二叉树的最大深度

解题思路

前提:二叉树的最大深度,等价于二叉树的层数,等价于求最底层二叉树叶子结点的高度。
思路:求二叉树深度:前序遍历;求二叉树高度:后序遍历;求二叉树层数:层级遍历。
重点:二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始);二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)。

代码实现

C语言
层级遍历 队列
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int maxDepth(struct TreeNode* root) {
    int ans = 0;
    // 判断树非空
    if (root == NULL)
    {
        return ans;
    }
    // 层级遍历, 队列
    struct TreeNode *queue[10000];
    int idx = 0;
    queue[idx++] = root;
    int start = 0;
    while (start < idx)
    {
        int levelCnt = idx - start;
        for (int i = 0; i < levelCnt; i++)
        {
            struct TreeNode *cur = queue[start++];
            if (cur->left)
            {
                queue[idx++] = cur->left;
            }
            if (cur->right)
            {
                queue[idx++] = cur->right;
            }
        }
        ans++;
    }
    return ans;
}
后序遍历 求root的高度,递归
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

int max(int a, int b)
{
    return (a > b) ? a : b;
}

int hight(struct TreeNode* root)
{
    // 后序遍历求高度,最大深度即为root的高度
    if (root == NULL)
    {
        return 0;
    }
    int leftHight = hight(root->left);
    int rightHight = hight(root->right);
    return 1 + max(leftHight, rightHight);
}

int maxDepth(struct TreeNode* root) {
    // 后序遍历求高度,最大深度即为root的高度,递归
    return hight(root);
}
前序遍历 求root深度,递归
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

int max(int a, int b)
{
    return (a > b) ? a : b;
}

void depthFun(struct TreeNode* root, int depth, int *result)
{
    // 前序遍历求深度, 注意回溯的过程
    if (root == NULL)
    {
        return ;
    }
    *result = max(*result, depth);
    depthFun(root->left, depth + 1, result);
    depthFun(root->right, depth + 1, result);
    return ;
}

int maxDepth(struct TreeNode* root) {
    // 后序遍历求高度,最大深度即为root的高度,递归
    int result = 0;
    int depth = 0;
    depthFun(root, depth + 1, &result);
    return result;
}

[111] 二叉树的最小深度

题目描述

111 二叉树的最小深度
111 二叉树的最小深度

解题思路

前提:二叉树的最小深度,等价于二叉树最高层叶子结点的层数,等价于求二叉树最高层叶子结点的高度。
思路:求二叉树深度:前序遍历;求二叉树高度:后序遍历;求二叉树层数:层级遍历。
重点:注意叶子结点的含义: (node->left == NULL) && (node->right == NULL)。

代码实现

C语言
层序遍历,队列
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int minDepth(struct TreeNode* root) {
    int ans = 0;
    // 判断空树
    if (root == NULL)
    {
        return ans;
    }
    // 层序遍历,队列
    struct TreeNode *queue[100000];
    int idx = 0;
    queue[idx++] = root;
    int start = 0;
    while (start < idx)
    {
        int levelCnt = idx - start;
        ans++;
        for (int i = 0; i < levelCnt; i++)
        {
            struct TreeNode *cur = queue[start++];
            // 判断是否为叶子结点
            if ((cur->left == NULL) && (cur->right == NULL))
            {
                // 找到第一个叶子结点,直接退出
                return ans;
            }
            if (cur->left)
            {
                queue[idx++] = cur->left;
            }
            if (cur->right)
            {
                queue[idx++] = cur->right;
            }
        }
    }
    return ans;
}
前序遍历深度,递归
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

int minFun(int a, int b)
{
    return (a < b) ? a : b;
}

void depthFun(struct TreeNode* root, int depth, int *result)
{
    if (NULL == root)
    {
        return ;
    }
    // 寻找叶子结点
    if ((root->left == NULL) && (root->right == NULL))
    {
        *result = minFun(*result, depth);
        return ;
    }
    depthFun(root->left, depth + 1, result);
    depthFun(root->right, depth + 1, result);
}

int minDepth(struct TreeNode* root) {
    // 判断空树
    if (root == NULL)
    {
        return 0;
    }
    int ans = INT_MAX;
    // 前序遍历,递归
    depthFun(root, 1, &ans);
    
    return ans;
}

[222] 完全二叉树的节点个数

题目描述

222 完全二叉树的节点个数
222 完全二叉树的节点个数

解题思路

前提:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2^(h-1) 个节点。
思路:普通二叉树遍历;利用完全二叉树特性,拆解为n个满二叉树,利用 2^树深度 - 1 来计算。
重点:完全二叉树的特性。

代码实现

C语言
普通二叉树 先序遍历 递归
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

void travesal(struct TreeNode *root, int *ans)
{
    if (root == NULL)
    {
        return ;
    }
    //先序遍历
    (*ans)++;
    travesal(root->left, ans);
    travesal(root->right, ans);
}

int countNodes(struct TreeNode* root) {
    int ans = 0;
    travesal(root, &ans);
    return ans;
}
普通二叉树 结点数量 递归
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

int countNodeNum(struct TreeNode *root)
{
    if (root == NULL)
    {
        return 0;
    }
    int leftNum = countNodeNum(root->left);
    int rightNum = countNodeNum(root->right);
    return (leftNum + rightNum + 1);
}

int countNodes(struct TreeNode* root) {
    int ans = countNodeNum(root);
    return ans;
}
完全二叉树分解成满二叉树,利用满二叉树结点数为2^n -1。
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

int countNodeNum(struct TreeNode *root)
{
    if (root == NULL)
    {
        return 0;
    }
    int leftDepth = 0;
    int rightDepth = 0;
    struct TreeNode *left = root->left;
    struct TreeNode *right = root->right;
    // 求左侧叶子结点的深度
    while (left)
    {
        leftDepth++;
        left = left->left;
    }
    // 求右侧叶子结点的深度
    while (right)
    {
        rightDepth++;
        right = right->right;
    }
    // 判断是否为满二叉树, 两边深度相同
    // 注意:两侧深度相同的二叉树不是满二叉树,但两侧深度相同的完全二叉树,一定是满二叉树。
    if (leftDepth == rightDepth)
    {
        return (2 << leftDepth) - 1;
    }
    int leftNum = countNodeNum(root->left);
    int rightNum = countNodeNum(root->right);
    return (leftNum + rightNum + 1);
}

int countNodes(struct TreeNode* root) {
    int ans = countNodeNum(root);
    return ans;
}

今日收获

  1. 二叉树的深度、高度;
  2. 完全二叉树的特性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值