解法一
思路和算法
陆地游乐设施的数量是 $n$,水上游乐设施的数量是 $m$。最直观的思路是遍历游客完成两个游乐设施的所有方案计算完成时间,得到最早完成时间。由于陆地游乐设施和水上游乐设施应各选择一种,两种游乐设施的顺序不限,因此所有方案数是 $2nm$,时间复杂度是 $O(nm)$。
代码
###Java
class Solution {
public int earliestFinishTime(int[] landStartTime, int[] landDuration, int[] waterStartTime, int[] waterDuration) {
int earliest1 = earliestFinishTimeWithOrder(landStartTime, landDuration, waterStartTime, waterDuration);
int earliest2 = earliestFinishTimeWithOrder(waterStartTime, waterDuration, landStartTime, landDuration);
return Math.min(earliest1, earliest2);
}
public int earliestFinishTimeWithOrder(int[] firstStartTime, int[] firstDuration, int[] secondStartTime, int[] secondDuration) {
int earliest = Integer.MAX_VALUE;
int firstLength = firstStartTime.length, secondLength = secondStartTime.length;
for (int i = 0; i < firstLength; i++) {
int firstEndTime = firstStartTime[i] + firstDuration[i];
for (int j = 0; j < secondLength; j++) {
int secondEndTime = Math.max(firstEndTime, secondStartTime[j]) + secondDuration[j];
earliest = Math.min(earliest, secondEndTime);
}
}
return earliest;
}
}
###C#
public class Solution {
public int EarliestFinishTime(int[] landStartTime, int[] landDuration, int[] waterStartTime, int[] waterDuration) {
int earliest1 = EarliestFinishTimeWithOrder(landStartTime, landDuration, waterStartTime, waterDuration);
int earliest2 = EarliestFinishTimeWithOrder(waterStartTime, waterDuration, landStartTime, landDuration);
return Math.Min(earliest1, earliest2);
}
public int EarliestFinishTimeWithOrder(int[] firstStartTime, int[] firstDuration, int[] secondStartTime, int[] secondDuration) {
int earliest = int.MaxValue;
int firstLength = firstStartTime.Length, secondLength = secondStartTime.Length;
for (int i = 0; i < firstLength; i++) {
int firstEndTime = firstStartTime[i] + firstDuration[i];
for (int j = 0; j < secondLength; j++) {
int secondEndTime = Math.Max(firstEndTime, secondStartTime[j]) + secondDuration[j];
earliest = Math.Min(earliest, secondEndTime);
}
}
return earliest;
}
}
###C++
class Solution {
public:
int earliestFinishTime(vector<int>& landStartTime, vector<int>& landDuration, vector<int>& waterStartTime, vector<int>& waterDuration) {
int earliest1 = earliestFinishTimeWithOrder(landStartTime, landDuration, waterStartTime, waterDuration);
int earliest2 = earliestFinishTimeWithOrder(waterStartTime, waterDuration, landStartTime, landDuration);
return min(earliest1, earliest2);
}
int earliestFinishTimeWithOrder(vector<int>& firstStartTime, vector<int>& firstDuration, vector<int>& secondStartTime, vector<int>& secondDuration) {
int earliest = INT_MAX;
int firstLength = firstStartTime.size(), secondLength = secondStartTime.size();
for (int i = 0; i < firstLength; i++) {
int firstEndTime = firstStartTime[i] + firstDuration[i];
for (int j = 0; j < secondLength; j++) {
int secondEndTime = max(firstEndTime, secondStartTime[j]) + secondDuration[j];
earliest = min(earliest, secondEndTime);
}
}
return earliest;
}
};
###Python
class Solution:
def earliestFinishTime(self, landStartTime: List[int], landDuration: List[int], waterStartTime: List[int], waterDuration: List[int]) -> int:
def earliestFinishTimeWithOrder(firstStartTime: List[int], firstDuration: List[int], secondStartTime: List[int], secondDuration: List[int]) -> int:
earliest = inf
firstLength, secondLength = len(firstStartTime), len(secondStartTime)
for i in range(firstLength):
firstEndTime = firstStartTime[i] + firstDuration[i]
for j in range(secondLength):
secondEndTime = max(firstEndTime, secondStartTime[j]) + secondDuration[j]
earliest = min(earliest, secondEndTime)
return earliest
earliest1 = earliestFinishTimeWithOrder(landStartTime, landDuration, waterStartTime, waterDuration)
earliest2 = earliestFinishTimeWithOrder(waterStartTime, waterDuration, landStartTime, landDuration)
return min(earliest1, earliest2)
###C
int earliestFinishTimeWithOrder(int* firstStartTime, int firstStartTimeSize, int* firstDuration, int firstDurationSize, int* secondStartTime, int secondStartTimeSize, int* secondDuration, int secondDurationSize) {
int earliest = INT_MAX;
for (int i = 0; i < firstStartTimeSize; i++) {
int firstEndTime = firstStartTime[i] + firstDuration[i];
for (int j = 0; j < secondStartTimeSize; j++) {
int secondEndTime = fmax(firstEndTime, secondStartTime[j]) + secondDuration[j];
earliest = fmin(earliest, secondEndTime);
}
}
return earliest;
}
int earliestFinishTime(int* landStartTime, int landStartTimeSize, int* landDuration, int landDurationSize, int* waterStartTime, int waterStartTimeSize, int* waterDuration, int waterDurationSize) {
int earliest1 = earliestFinishTimeWithOrder(landStartTime, landStartTimeSize, landDuration, landDurationSize, waterStartTime, waterStartTimeSize, waterDuration, waterDurationSize);
int earliest2 = earliestFinishTimeWithOrder(waterStartTime, waterStartTimeSize, waterDuration, waterDurationSize, landStartTime, landStartTimeSize, landDuration, landDurationSize);
return fmin(earliest1, earliest2);
}
###Go
func earliestFinishTime(landStartTime []int, landDuration []int, waterStartTime []int, waterDuration []int) int {
earliest1 := earliestFinishTimeWithOrder(landStartTime, landDuration, waterStartTime, waterDuration)
earliest2 := earliestFinishTimeWithOrder(waterStartTime, waterDuration, landStartTime, landDuration)
return min(earliest1, earliest2)
}
func earliestFinishTimeWithOrder(firstStartTime []int, firstDuration []int, secondStartTime []int, secondDuration []int) int {
earliest := math.MaxInt
firstLength, secondLength := len(firstStartTime), len(secondStartTime)
for i := 0; i < firstLength; i++ {
firstEndTime := firstStartTime[i] + firstDuration[i]
for j := 0; j < secondLength; j++ {
secondEndTime := max(firstEndTime, secondStartTime[j]) + secondDuration[j]
earliest = min(earliest, secondEndTime)
}
}
return earliest
}
###JavaScript
var earliestFinishTime = function(landStartTime, landDuration, waterStartTime, waterDuration) {
let earliest1 = earliestFinishTimeWithOrder(landStartTime, landDuration, waterStartTime, waterDuration);
let earliest2 = earliestFinishTimeWithOrder(waterStartTime, waterDuration, landStartTime, landDuration);
return Math.min(earliest1, earliest2);
};
var earliestFinishTimeWithOrder = function(firstStartTime, firstDuration, secondStartTime, secondDuration) {
let earliest = Infinity;
let firstLength = firstStartTime.length, secondLength = secondStartTime.length;
for (let i = 0; i < firstLength; i++) {
let firstEndTime = firstStartTime[i] + firstDuration[i];
for (let j = 0; j < secondLength; j++) {
let secondEndTime = Math.max(firstEndTime, secondStartTime[j]) + secondDuration[j];
earliest = Math.min(earliest, secondEndTime);
}
}
return earliest;
};
###TypeScript
function earliestFinishTime(landStartTime: number[], landDuration: number[], waterStartTime: number[], waterDuration: number[]): number {
let earliest1 = earliestFinishTimeWithOrder(landStartTime, landDuration, waterStartTime, waterDuration);
let earliest2 = earliestFinishTimeWithOrder(waterStartTime, waterDuration, landStartTime, landDuration);
return Math.min(earliest1, earliest2);
};
function earliestFinishTimeWithOrder(firstStartTime: number[], firstDuration: number[], secondStartTime: number[], secondDuration: number[]): number {
let earliest = Infinity;
let firstLength = firstStartTime.length, secondLength = secondStartTime.length;
for (let i = 0; i < firstLength; i++) {
let firstEndTime = firstStartTime[i] + firstDuration[i];
for (let j = 0; j < secondLength; j++) {
let secondEndTime = Math.max(firstEndTime, secondStartTime[j]) + secondDuration[j];
earliest = Math.min(earliest, secondEndTime);
}
}
return earliest;
};
复杂度分析
解法二
思路和算法
当两种游乐设施的顺序确定时,为了使完成时间最早,第一个体验的游乐设施应选择结束时间最早的游乐设施。
具体见题解「3635. 最早完成陆地和水上游乐设施的时间 II」。
代码
###Java
class Solution {
public int earliestFinishTime(int[] landStartTime, int[] landDuration, int[] waterStartTime, int[] waterDuration) {
int earliest1 = earliestFinishTimeWithOrder(landStartTime, landDuration, waterStartTime, waterDuration);
int earliest2 = earliestFinishTimeWithOrder(waterStartTime, waterDuration, landStartTime, landDuration);
return Math.min(earliest1, earliest2);
}
public int earliestFinishTimeWithOrder(int[] firstStartTime, int[] firstDuration, int[] secondStartTime, int[] secondDuration) {
int earliest = Integer.MAX_VALUE;
int firstLength = firstStartTime.length, secondLength = secondStartTime.length;
int minFirstEndTime = Integer.MAX_VALUE;
for (int i = 0; i < firstLength; i++) {
int firstEndTime = firstStartTime[i] + firstDuration[i];
minFirstEndTime = Math.min(minFirstEndTime, firstEndTime);
}
for (int j = 0; j < secondLength; j++) {
int secondEndTime = Math.max(minFirstEndTime, secondStartTime[j]) + secondDuration[j];
earliest = Math.min(earliest, secondEndTime);
}
return earliest;
}
}
###C#
public class Solution {
public int EarliestFinishTime(int[] landStartTime, int[] landDuration, int[] waterStartTime, int[] waterDuration) {
int earliest1 = EarliestFinishTimeWithOrder(landStartTime, landDuration, waterStartTime, waterDuration);
int earliest2 = EarliestFinishTimeWithOrder(waterStartTime, waterDuration, landStartTime, landDuration);
return Math.Min(earliest1, earliest2);
}
public int EarliestFinishTimeWithOrder(int[] firstStartTime, int[] firstDuration, int[] secondStartTime, int[] secondDuration) {
int earliest = int.MaxValue;
int firstLength = firstStartTime.Length, secondLength = secondStartTime.Length;
int minFirstEndTime = int.MaxValue;
for (int i = 0; i < firstLength; i++) {
int firstEndTime = firstStartTime[i] + firstDuration[i];
minFirstEndTime = Math.Min(minFirstEndTime, firstEndTime);
}
for (int j = 0; j < secondLength; j++) {
int secondEndTime = Math.Max(minFirstEndTime, secondStartTime[j]) + secondDuration[j];
earliest = Math.Min(earliest, secondEndTime);
}
return earliest;
}
}
###C++
class Solution {
public:
int earliestFinishTime(vector<int>& landStartTime, vector<int>& landDuration, vector<int>& waterStartTime, vector<int>& waterDuration) {
int earliest1 = earliestFinishTimeWithOrder(landStartTime, landDuration, waterStartTime, waterDuration);
int earliest2 = earliestFinishTimeWithOrder(waterStartTime, waterDuration, landStartTime, landDuration);
return min(earliest1, earliest2);
}
int earliestFinishTimeWithOrder(vector<int>& firstStartTime, vector<int>& firstDuration, vector<int>& secondStartTime, vector<int>& secondDuration) {
int earliest = INT_MAX;
int firstLength = firstStartTime.size(), secondLength = secondStartTime.size();
int minFirstEndTime = INT_MAX;
for (int i = 0; i < firstLength; i++) {
int firstEndTime = firstStartTime[i] + firstDuration[i];
minFirstEndTime = min(minFirstEndTime, firstEndTime);
}
for (int j = 0; j < secondLength; j++) {
int secondEndTime = max(minFirstEndTime, secondStartTime[j]) + secondDuration[j];
earliest = min(earliest, secondEndTime);
}
return earliest;
}
};
###Python
class Solution:
def earliestFinishTime(self, landStartTime: List[int], landDuration: List[int], waterStartTime: List[int], waterDuration: List[int]) -> int:
def earliestFinishTimeWithOrder(firstStartTime: List[int], firstDuration: List[int], secondStartTime: List[int], secondDuration: List[int]) -> int:
earliest = inf
firstLength, secondLength = len(firstStartTime), len(secondStartTime)
minFirstEndTime = inf
for i in range(firstLength):
firstEndTime = firstStartTime[i] + firstDuration[i]
minFirstEndTime = min(minFirstEndTime, firstEndTime)
for j in range(secondLength):
secondEndTime = max(minFirstEndTime, secondStartTime[j]) + secondDuration[j]
earliest = min(earliest, secondEndTime)
return earliest
earliest1 = earliestFinishTimeWithOrder(landStartTime, landDuration, waterStartTime, waterDuration)
earliest2 = earliestFinishTimeWithOrder(waterStartTime, waterDuration, landStartTime, landDuration)
return min(earliest1, earliest2)
###C
int earliestFinishTimeWithOrder(int* firstStartTime, int firstStartTimeSize, int* firstDuration, int firstDurationSize, int* secondStartTime, int secondStartTimeSize, int* secondDuration, int secondDurationSize) {
int earliest = INT_MAX;
int minFirstEndTime = INT_MAX;
for (int i = 0; i < firstStartTimeSize; i++) {
int firstEndTime = firstStartTime[i] + firstDuration[i];
minFirstEndTime = fmin(minFirstEndTime, firstEndTime);
}
for (int j = 0; j < secondStartTimeSize; j++) {
int secondEndTime = fmax(minFirstEndTime, secondStartTime[j]) + secondDuration[j];
earliest = fmin(earliest, secondEndTime);
}
return earliest;
}
int earliestFinishTime(int* landStartTime, int landStartTimeSize, int* landDuration, int landDurationSize, int* waterStartTime, int waterStartTimeSize, int* waterDuration, int waterDurationSize) {
int earliest1 = earliestFinishTimeWithOrder(landStartTime, landStartTimeSize, landDuration, landDurationSize, waterStartTime, waterStartTimeSize, waterDuration, waterDurationSize);
int earliest2 = earliestFinishTimeWithOrder(waterStartTime, waterStartTimeSize, waterDuration, waterDurationSize, landStartTime, landStartTimeSize, landDuration, landDurationSize);
return fmin(earliest1, earliest2);
}
###Go
func earliestFinishTime(landStartTime []int, landDuration []int, waterStartTime []int, waterDuration []int) int {
earliest1 := earliestFinishTimeWithOrder(landStartTime, landDuration, waterStartTime, waterDuration)
earliest2 := earliestFinishTimeWithOrder(waterStartTime, waterDuration, landStartTime, landDuration)
return min(earliest1, earliest2)
}
func earliestFinishTimeWithOrder(firstStartTime []int, firstDuration []int, secondStartTime []int, secondDuration []int) int {
earliest := math.MaxInt
firstLength, secondLength := len(firstStartTime), len(secondStartTime)
minFirstEndTime := math.MaxInt
for i := 0; i < firstLength; i++ {
firstEndTime := firstStartTime[i] + firstDuration[i]
minFirstEndTime = min(minFirstEndTime, firstEndTime)
}
for j := 0; j < secondLength; j++ {
secondEndTime := max(minFirstEndTime, secondStartTime[j]) + secondDuration[j]
earliest = min(earliest, secondEndTime)
}
return earliest
}
###JavaScript
var earliestFinishTime = function(landStartTime, landDuration, waterStartTime, waterDuration) {
let earliest1 = earliestFinishTimeWithOrder(landStartTime, landDuration, waterStartTime, waterDuration);
let earliest2 = earliestFinishTimeWithOrder(waterStartTime, waterDuration, landStartTime, landDuration);
return Math.min(earliest1, earliest2);
};
var earliestFinishTimeWithOrder = function(firstStartTime, firstDuration, secondStartTime, secondDuration) {
let earliest = Infinity;
let firstLength = firstStartTime.length, secondLength = secondStartTime.length;
let minFirstEndTime = Infinity;
for (let i = 0; i < firstLength; i++) {
let firstEndTime = firstStartTime[i] + firstDuration[i];
minFirstEndTime = Math.min(minFirstEndTime, firstEndTime);
}
for (let j = 0; j < secondLength; j++) {
let secondEndTime = Math.max(minFirstEndTime, secondStartTime[j]) + secondDuration[j];
earliest = Math.min(earliest, secondEndTime);
}
return earliest;
};
###TypeScript
function earliestFinishTime(landStartTime: number[], landDuration: number[], waterStartTime: number[], waterDuration: number[]): number {
let earliest1 = earliestFinishTimeWithOrder(landStartTime, landDuration, waterStartTime, waterDuration);
let earliest2 = earliestFinishTimeWithOrder(waterStartTime, waterDuration, landStartTime, landDuration);
return Math.min(earliest1, earliest2);
};
function earliestFinishTimeWithOrder(firstStartTime: number[], firstDuration: number[], secondStartTime: number[], secondDuration: number[]): number {
let earliest = Infinity;
let firstLength = firstStartTime.length, secondLength = secondStartTime.length;
let minFirstEndTime = Infinity;
for (let i = 0; i < firstLength; i++) {
let firstEndTime = firstStartTime[i] + firstDuration[i];
minFirstEndTime = Math.min(minFirstEndTime, firstEndTime);
}
for (let j = 0; j < secondLength; j++) {
let secondEndTime = Math.max(minFirstEndTime, secondStartTime[j]) + secondDuration[j];
earliest = Math.min(earliest, secondEndTime);
}
return earliest;
};
复杂度分析