LeetCode 每日一题笔记 日期:2026.06.02 题目:3633. 最早完成陆地和水上游乐设施的时间 I

LeetCode 每日一题笔记

0. 前言

  • 日期:2026.06.02
  • 题目:3633. 最早完成陆地和水上游乐设施的时间 I
  • 难度:简单
  • 标签:数组、贪心

1. 题目理解

问题描述

必须恰好选1个陆地项目、1个水上项目,游玩顺序二选一:先陆地后水上 / 先水上后陆地;项目最早只能在自身startTime开启,结束后立刻开启下一个项目,下一个项目若还没到开启时间就等待到开启,求全部游玩完毕的最小结束时间。

示例

输入:landStartTime=1,4,landDuration=3,2,waterStartTime=3,5,waterDuration=2,1

输出:6

2. 解题思路

核心观察

  1. 单个项目单独游玩的结束时间 = start + duration;
  2. 只有两种游玩顺序,最优解一定出自「陆地最优单品搭配水上最优单品」;
  3. 顺序1:先陆地→水上:陆地结束时间A,水上开始=max(水上start,A),总结束=开始+水上时长;
  4. 顺序2:先水上→陆地:水上结束时间B,陆地开始=max(陆地start,B),总结束=开始+陆地时长;
  5. 两种顺序结果取最小即为答案。

算法步骤

  1. 遍历陆地数组,求出单独游玩结束最早的陆地minLandEnd;
  2. 用minLandEnd逐个搭配所有水上项目,算出先陆后水的全局最优min1;
  3. 遍历水上数组,求出单独游玩结束最早的水上minWaterEnd;
  4. 用minWaterEnd逐个搭配所有陆地项目,算出先水后陆的全局最优min2;
  5. return min(min1,min2)。

3. 代码实现

java 复制代码
package lc3600_lc3699.lc3633;

class Solution {
    public int earliestFinishTime(int[] landStartTime, int[] landDuration, int[] waterStartTime, int[] waterDuration) {
        int res = Integer.MAX_VALUE;
        for (int i = 0; i < landStartTime.length; i++) {
            int ls = landStartTime[i];
            int ld = landDuration[i];
            for (int j = 0; j < waterStartTime.length; j++) {
                int ws = waterStartTime[j];
                int wd = waterDuration[j];
                int end1 = Math.max(ls, 0) + ld;
                end1 = Math.max(ws, end1) + wd;
                int end2 = Math.max(ws, 0) + wd;
                end2 = Math.max(ls, end2) + ld;
                res = Math.min(res, Math.min(end1, end2));
            }
        }
        return res;
    }
}

4. 代码优化说明

(原优化代码保留不变,附加行注释)

java 复制代码
class Solution {
public int earliestFinishTime(int[] landStartTime, int[] landDuration, int[] waterStartTime, int[] waterDuration) {
int n = landStartTime.length;
int minEnd = Integer.MAX_VALUE;
// 遍历陆地,筛选单独游玩结束时间最小的陆地项目
for(int i=0;i<n;i++){
if(landStartTime[i]+landDuration[i]<minEnd){
minEnd = landStartTime[i]+landDuration[i];
}
}
int minEnd2 = Integer.MAX_VALUE;
// 用最优陆地搭配所有水上,求【先陆地后水上】最小结束时间
for(int i=0;i<waterStartTime.length;i++){
int s = Math.max(minEnd,waterStartTime[i]);
if(s+waterDuration[i]<minEnd2){
minEnd2 = s+waterDuration[i];
}
}
int minEnd3 = Integer.MAX_VALUE;
// 遍历水上,筛选单独游玩结束时间最小的水上项目
for(int i=0;i<waterStartTime.length;i++){
if(waterStartTime[i]+waterDuration[i]<minEnd3){
minEnd3 = waterStartTime[i]+waterDuration[i];
}
}
int minEnd4 = Integer.MAX_VALUE;
// 用最优水上搭配所有陆地,求【先水上后陆地】最小结束时间
for(int i=0;i<n;i++){
int s = Math.max(minEnd3,landStartTime[i]);
if(s+landDuration[i]<minEnd4){
minEnd4 = s+landDuration[i];
}
}
// 两种游玩方案取最小值
return Math.min(minEnd2,minEnd4);
    }
}

5. 复杂度分析

  • 暴力双重循环:时间O(N⋅M)O(N \cdot M)O(N⋅M),空间O(1)O(1)O(1)
  • 贪心优化版:时间O(N+M)O(N+M)O(N+M),空间O(1)O(1)O(1)

6. 总结

  • 贪心关键点:全局最优一定是单品最优互相组合,不用全量枚举所有配对;
  • 只分先后两种游玩次序,分别计算最优再对比即可;
  • 优化把平方复杂度降为线性,大数据下效率提升明显。
相关推荐
洛水水1 小时前
【力扣100题】85.每日温度
算法·leetcode·职场和发展
Coder-magician1 小时前
《代码随想录》刷题打卡day15:二叉树part05
数据结构·c++·算法
Kurisu_红莉栖1 小时前
力扣56合并区间
算法·leetcode
Irissgwe1 小时前
算法的时间复杂度和空间复杂度
数据结构·c++·算法·c·时间复杂度·空间复杂度
随意起个昵称1 小时前
区间dp-基础题目3(永别)
c++·算法
周末也要写八哥1 小时前
有向图Hierholzer算法的另一种实现
算法
bIo7lyA8v1 小时前
算法调优中的性能回归与基准测试分析的技术8
算法·数据挖掘·回归
有点。1 小时前
C++贪心算法二(练习题)
c++·算法·贪心算法
西安邮电大学1 小时前
贪心算法详细讲解
java·后端·其他·算法·面试
开源Z1 小时前
LeetCode 135 · 分发糖果:两次扫描,先左后右取最大
算法·leetcode