3635. 最早完成陆地和水上游乐设施的时间II

先尝试1的解题方案,要么是先完成陆地设施,然后是水上设施,要么是先完成水上设施然后是陆地设施,

因此对于每种方案,只要找到第二个完成的最早开始时间,即max(第一个设施结束时间,第二个设施开始时间),然后加上第二个项目的持续时间,这样就合理了。

java 复制代码
class Solution {
    public int earliestFinishTime(int[] landStartTime, int[] landDuration, int[] waterStartTime, int[] waterDuration) {
        int n = landStartTime.length;
        int m = waterStartTime.length;

        int minTime = Integer.MAX_VALUE;

        for (int i = 0; i < n; i++) {
            // 获取当前陆地时间
            int landStart = landStartTime[i];
            int landEnd = landStart + landDuration[i];

            // 遍历水上时间
            for (int j = 0; j < m; j++) {
                // 获取水上时间
                int waterStart = waterStartTime[j];
                int waterEnd = waterDuration[j] + waterStart;

                // 假设是先陆地后水上
                // 获取水上的最晚开始时间,也就是等陆地完成
                int actualWaterStart = Math.max(landEnd, waterStart);
                int totalTime1 = actualWaterStart + waterDuration[j];

                // 先水上后陆地,也就是等水上完成
                int actualLandStart = Math.max(waterEnd, landStart);
                int totalTime2 = actualLandStart + landDuration[i];

                minTime = Math.min(minTime, Math.min(totalTime1, totalTime2));
            }
        }
        return minTime;
    }
}

显然是暴力枚举讨论的,双重循环,在当前数据量的情况下会超时,

找到优化的地方,既然这个时间是max(第一个设施结束时间,第二个设施开始时间),可以发现表达式随着第一个设施结束时间是增大单调不减的,

所以为了使最终完成时间最小,只需要保留第一类项目中的最早结束时间即可。

同理另外一个先水上后陆地也是一样的道理。

所以先找到陆地结束时间最小,再计算水上结束时间最小,即可

反过来,计算水上结束时间最小,再计算陆地结束时间最小,

java 复制代码
class Solution {
    public int earliestFinishTime(int[] landStartTime, int[] landDuration, int[] waterStartTime, int[] waterDuration) {
        // 公共方法,
        int time1 = solve(landStartTime, landDuration, waterStartTime, waterDuration);
        int time2 = solve(waterStartTime, waterDuration, landStartTime, landDuration);
        return Math.min(time1, time2);
    }

    private int solve(int[] start1, int[] duration1, int[] start2, int[] duration2) {
        // 先找出第一个最早结束时间
        int finish1 = Integer.MAX_VALUE;
        for (int i = 0; i < start1.length; i++) {
            finish1 = Math.min(finish1, start1[i] + duration1[i]);
        }
        // 第二个的最早结束时间
        int finish2 = Integer.MAX_VALUE;
        for (int j = 0; j < start2.length; j++) {
            finish2 = Math.min(finish2, Math.max(start2[j], finish1) + duration2[j]);
        }

        return finish2;
    }
}

这样就从O(nm)优化到O(n + m),线性复杂度。

相关推荐
木井巳3 小时前
【DFS解决floodfill算法】岛屿的最大面积
java·算法·leetcode·深度优先
yyds_yyd_100863 小时前
877. 石子游戏(2026.08.02)& 486. 预测赢家(2026.08.01)
c++·leetcode
普通攻击往后拉14 小时前
Leetcode 206. 反转链表
算法·leetcode·链表
橘子汽水16821 小时前
Leetcode 230,98:二叉搜索树中第K小的元素,验证二叉搜索树
算法·leetcode·职场和发展
普通攻击往后拉1 天前
Leetcode 448. 找到所有数组中消失的数字
算法·leetcode·职场和发展
mifengxing1 天前
LeetCode 189 轮转数组|3种解法拆解,从暴力到O(1)原地最优解
数据结构·算法·leetcode
程序员-珍1 天前
力扣 877. 石子游戏
算法·leetcode·游戏
wabs6661 天前
关于链表【力扣19.删除链表的倒数第N个节点的思考】
数据结构·leetcode·链表
Rabitebla1 天前
C++ STL 之 set 详解:从底层红黑树到实际应用
开发语言·数据结构·c++·算法·leetcode
郝学胜-神的一滴1 天前
力扣 692:巧用小顶堆高效求解前K个高频单词
java·数据结构·python·程序人生·算法·leetcode·职场和发展