这是一个经典的贪心算法问题。

🧠 解题思路

1.  核心洞察:
    *   无论播种顺序如何,总的播种时间(所有 plantTime 之和)是固定的。
    *   为了让所有花尽早开放,我们应该让生长时间(growTime)长的花尽早开始生长。
    *   这就像操作系统中的 I/O 调度:让耗时长的 I/O 操作(生长)尽早开始,这样在它生长的时候,CPU(你)可以去处理其他任务(播种其他花)。

2.  贪心策略:
    *   将所有种子按照 growTime 从大到小排序。
    *   按照这个顺序依次播种。
    *   在播种过程中,记录每朵花的开花时间,并更新最晚开花时间。

3.  为什么这个策略最优?
    *   生长时间长的花如果晚种,会拖慢整体进度。
    *   先种生长时间长的花,可以让它在后台"并行"生长,而你在前台继续播种其他花。

💻 TypeScript 代码实现

function earliestFullBloom(plantTime: number[], growTime: number[]): number {
    const n = plantTime.length;
    
    // 创建索引数组,用于按 growTime 排序
    const indices: number[] = Array.from({ length: n }, (_, i) => i);
    
    // 按 growTime 降序排序
    indices.sort((i, j) => growTime[j] - growTime[i]);
    
    let currentTime = 0;  // 当前累计的播种时间
    let maxBloomTime = 0; // 记录最晚的开花时间
    
    // 按照排序后的顺序播种
    for (const i of indices) {
        currentTime += plantTime[i];  // 播种这朵花
        const bloomTime = currentTime + growTime[i];  // 这朵花的开花时间
        maxBloomTime = Math.max(maxBloomTime, bloomTime);  // 更新最晚开花时间
    }
    
    return maxBloomTime;
}

📝 算法步骤详解

1.  创建索引数组:indices[i] = i,用于保持原始数组的索引。
2.  排序:按照 growTime 降序排列索引数组。
3.  模拟播种过程:
    *   currentTime 记录到当前为止累计的播种时间。
    *   对于每朵花,先更新 currentTime(加上播种时间),然后计算它的开花时间(currentTime + growTime[i])。
    *   用 maxBloomTime 记录所有花中最晚的开花时间。
4.  返回结果:maxBloomTime 就是所有花都开花的最早一天。

📊 复杂度分析

*   时间复杂度:O(n log n)。主要消耗在排序上,遍历过程是 O(n)。
*   空间复杂度:O(n)。用于存储索引数组。

🎯 示例说明

以 plantTime = [1,4,3], growTime = [2,3,1] 为例:

1.  按 growTime 降序排序:种子1(grow=3), 种子0(grow=2), 种子2(grow=1)
2.  第0-3天:播种种子1(耗时4天),第4天开始生长
3.  第4天:播种种子0(耗时1天),第5天开始生长  
4.  第5-7天:播种种子2(耗时3天),第8天开始生长
5.  开花时间:种子1在第7天开花,种子0在第6天开花,种子2在第9天开花
6.  最晚是第9天,所以答案是9。㇏

 

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐