主持人调度(二)-C++-牛客BM96

一、题目

有 n 个活动即将举办,每个活动都有开始时间与活动的结束时间,第 i 个活动的开始时间是 starti ,第 i 个活动的结束时间是 endi ,举办某个活动就需要为该活动准备一个活动主持人。
一位活动主持人在同一时间只能参与一个活动。并且活动主持人需要全程参与活动,换句话说,一个主持人参与了第 i 个活动,那么该主持人在 (starti,endi) 这个时间段不能参与其他任何活动。求为了成功举办这 n 个活动,最少需要多少名主持人。

 

二、思路

首先根据每个活动的开始时间对活动进行排序,然后用一个集合endtime(multiset类型)来保存已经使用的主持人的结束时间(允许重复值,自动升序排序),遍历活动数组,如果当前活动的开始时间晚于最早结束活动的主持人时间(endtime的第一个值),则不用增加主持人,将这个活动安排给最早结束活动的主持人来主持即可(将endtime的第一个值设置为当前活动的结束时间,先删除,后插入新增),如果当前活动的开始时间早于最早结束的主持人的活动(endtime的第一个值),则需要另外增加主持人,当前活动的结束时间就是新增加的主持人的主持结束时间(将当前活动的结束时间查出到endtime中,不用先删除)最后,endtime的最大值就是所需要的主持人数量。

三、代码

class Solution {
public:
    int minmumNumberOfHost(int n, vector<vector<int> >& startEnd) {
        if(n == 0) return 0;
        sort(startEnd.begin(), startEnd.end(), cmp);
        int ans = 0;
        multiset<int> endtime; //保存每个主持人的结束时间(自动升序)
        for(int i=0; i<n; i++){
            if(startEnd[i][0] >= *endtime.begin()){
                endtime.erase(*endtime.begin());
            }
            endtime.insert(startEnd[i][1]); //将当前活动的结束时间加入集合
            if(endtime.size() > ans) 
                ans = endtime.size();
        }
        return ans;
    }
    //每个活动按开始时间升序排序
    static bool cmp(vector<int> a, vector<int> b){
        return a[0] < b[0];
    }
};

### 牛客 BM2 的 C++ 实现 BM2 是一道经典的算法题目,主要涉及叉树的最大路径和问题。以下是基于已知信息以及常见解决思路给出的 C++ 实现。 #### 方法概述 该问题可以通过 **动态规划** 和 **递归回溯** 来求解。核心思想是从根节点出发,计算经过任意节点的最大路径和。对于每一个节点,其贡献可以分为两种情况: 1. 节点作为路径的一部分(单边向下延伸)。 2. 节点成为路径的转折点(左子树 + 右子树 + 当前节点值)。 最终通过递归的方式自底向上更新全局最大值。 --- #### C++ 实现代码 ```cpp /** * Definition for a binary tree node. */ struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} }; class Solution { public: int maxPathSum(TreeNode* root) { if (!root) return INT_MIN; // 边界条件处理 int globalMax = INT_MIN; helper(root, globalMax); return globalMax; } private: int helper(TreeNode* node, int& globalMax) { if (!node) return 0; // 左右子树的最大贡献值,忽略负数部分 int leftGain = std::max(helper(node->left, globalMax), 0); int rightGain = std::max(helper(node->right, globalMax), 0); // 更新当前节点为路径转折点时的最大值 int currentMax = node->val + leftGain + rightGain; globalMax = std::max(globalMax, currentMax); // 返回以当前节点为起点的一侧最大路径和 return node->val + std::max(leftGain, rightGain); } }; ``` --- #### 关键点解析 1. **递归函数设计** - `helper` 函数用于计算以某个节点为根的最大路径和,并将其结果存储到 `globalMax` 中。 - 对于每个节点,分别考虑左侧和右侧子树的最大贡献值[^3]。 2. **边界条件** - 如果当前节点为空,则返回 0 表示无贡献。 - 使用 `INT_MIN` 初始化全局变量 `globalMax`,确保能够正确记录最小可能值。 3. **优化细节** - 避免重复计算子树的最大路径和,利用递归特性一次完成所有节点的访问。 --- #### 时间空间复杂度分析 - **时间复杂度**: O(n),其中 n 是叉树中节点的数量。每个节点仅被访问一次。 - **空间复杂度**: O(h),h 是叉树的高度。最坏情况下(退化成链表),空间复杂度为 O(n)[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值