LeetCode 543.二叉树的直径 C语言

本文介绍了两种求解二叉树最大直径的方法:一种是先序遍历每个节点并更新最大直径,另一种是使用自底向上的DFS,通过记录每层的深度找到最大直径。前者时间复杂度较高,后者更节省时间。

方法一:遍历每个节点的直径取最大值

看到这个题我的第一个反应是遍历二叉树中的每一个节点,求出来以该节点为根的树的直径,然后去其中直径最大的值返回就行

int dia;

int deepth(struct TreeNode* root)
{
    if(!root)
        return 0;
    return fmax(deepth(root -> left), deepth(root -> right)) + 1;
}

void travel(struct TreeNode* root)
{
    if(root)
    {
        int dep = deepth(root -> left) + deepth(root -> right);
        dia = fmax(dia, dep);
        travel(root -> left);
        travel(root -> right);
    }
}

int diameterOfBinaryTree(struct TreeNode* root) {
    dia = 0;
    travel(root);
    return dia;
}

这里的travel函数是对二叉树进行先序遍历每个节点求节点最大直径的

至于最大直径的求法 就是左子树的深度加右子树的深度

需要注意的是题目中给的直径的定义是

        树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。

        两节点之间路径的 长度 由它们之间边数表示。

如上图 子树返回的深度恰好等于子树的最高的路径的边的数量加上根节点到子树的那一条边

比如说根为1的树 左子树最高的路径就是2到3或者2到4 边数为1 再加上2到1的那一条边 就是1+1=2就等于左子树的高度

这样一来每求出一个节点的最大直径就和已经访问过的节点中最大的直径比较 不断更新dia的值就能得到树的最大直径

方法二:

方法一比较好想,但每访问一个节点 就要遍历以节点为根的子树 时间复杂度就达到了n平方 有没有更省时的方法呢?

我们可以自下而上遍历树 返回每棵树的深度 这样每回到上一层递归函数直接得到了子树的深度 再通过与当前最大直径的比较就能得出树的最大直径

int max;

int DFS(struct TreeNode* root)
{
    if(!root)
        return 0;
    int left = DFS(root -> left);
    int right = DFS(root -> right);
    max = fmax(max, left + right);
    return fmax(left, right) + 1;
}

int diameterOfBinaryTree(struct TreeNode* root) {
    max = 0;
    DFS(root);
    return max;
}

其中max作为全局变量位于内存全局区 不会随函数在栈区的递归调用而改变

需要注意的是DFS返回值是当前树的最高路径的长度 而不是当树的最大直径 

### LeetCode 56 题目解析 LeetCode第56题要求解决区间合并的问题。给定一系列不重叠的区间,在这些区间中插入一个新的区间并进行合并,如果有必要的话[^1]。 ### 解决方案概述 为了有效地处理这个问题,可以先按照区间的起始位置对输入数组进行排序。接着遍历这个有序列表来判断当前区间是否与下一个区间有交集;如果有,则将这两个区间合并成一个更大的新区间继续比较下去直到完成整个过程[^2]。 ### C语言实现代码 下面是针对此问题的一个具体C语言解决方案: ```c #include <stdio.h> #include <stdlib.h> // 定义结构体表示区间 struct Interval { int start; int end; }; // 比较函数用于qsort()按start升序排列 int compare(const void* a, const void* b) { struct Interval *ia = (struct Interval *)a; struct Interval *ib = (struct Interval *)b; return ia->start - ib->start; } /** * Note: The returned array must be malloced, assume caller calls free(). */ struct Interval* merge(struct Interval* intervals, int intervalsSize, int* returnSize){ qsort(intervals, intervalsSize, sizeof(struct Interval), compare); // 动态分配内存存储结果 struct Interval *result = (struct Interval*)malloc(sizeof(struct Interval)*intervalsSize); *returnSize = 0; for (int i = 0; i < intervalsSize; ++i) { int L = intervals[i].start, R = intervals[i].end; if (!(*returnSize) || result[*returnSize-1].end < L) { result[(*returnSize)++] = intervals[i]; } else { result[*returnSize-1].end = fmax(result[*returnSize-1].end, R); } } return result; } ``` 该算法的时间复杂度主要取决于排序操作O(nlogn),其中n代表输入区间的数量。空间复杂度为O(1)(忽略返回的结果所占用的空间)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值