常搞不清楚換算?把題目給定的條件「單位」寫出來。題目給定一趟旅程所需時間 =
time[i]時間 / 趟,給定時間t,可以換算成總共可以完成t / time[i]次旅程,因為時間 / (時間 / 趟) = 趟。
Given a time t, then the number of trips that can be completed is t / time[i]. We can start from the minimum speed 1, and check if it's possible to complete all trips within the given time. If not, we check 2, then 3, and so on until we found the time that can complete all trips.
// t / time[i] = # trips >= totalTrips?
t = 1
1/1 + 1/2 + 1/3 = 1 + 0 + 0 = 1 < 5
t = 2
2/1 + 2/2 + 2/3 = 2 + 1 + 0 = 3 < 5
t = 3
3/1 + 3/2 + 3/3 = 3 + 1 + 1 = 5 >= 5
// -------------------------
totalTrips = 5
time = [1, 2, 3]
// The total trips that can be completed within the current time
t = 1 1 0 0 = 1 < 5 X
t = 2 2 1 0 = 3 < 5 X
t = 3 3 1 1 = 5 >= 5 O
t = 4 4 2 1 = 7 >= 5 O
t = 5 5 2 1 = 8 >= 5 O
t = 6 6 3 2 = 11 >= 5 Ofun minimumTime(time: IntArray, totalTrips: Int): Long {
var requiredTime = 1L
var trips = 0
while (trips < totalTrips) {
trips = 0
for (t in time) {
trips += requiredTime / t
}
if (totalTrips <= trips) break
requiredTime++
}
return requiredTime
}We can optimize the linear search solution with some modifications based on some key observations:
- If
time = tis sufficient, then anytime > tis also sufficient. - If
time = tis not sufficient, then anytime < tis also not sufficient.
This exhibits the monotonicity characteristic, the search space can be reduced efficiently by applying binary search. We can use binary search to find the minimum time: We're looking for the first element that satisfies the condition: totalTrips <= trips.
// required time
1 2 3 4 5 6 7, ...
[X, X, X, O, O, O, O]
^ // The minimum time to complete all trips时间越多,可以完成的旅途總次數也就越多,有单调性,可以二分答案。
- The minimum possible required time must at at least 1. A better lower bound is
min(time)because the fastest bus will complete one trip in that time. Let's take an example:
time = [3, 5, 7]
totalTrips = 12- The fastest bus will complete one trip in
3time. - The absolute minimum time to complete all trips cannot be less than
3. Because the fastest bus will complete one trip in3time, it's impossible to complete all trips (which is12) in less than3time.
The maximum time is min(time) * totalTrips, why? Let's take the same example above:
- If only the fastest bus is available in the worst case, then completing all trips will take
3 * 12 = 36time. Now we have more buses available, so the time will be less than36. - Or simply using
10^7from the problem constraints (not recommended).
fun minimumTime(time: IntArray, totalTrips: Int): Long {
val totalTrips = totalTrips.toLong()
var min = Long.MAX_VALUE
for (t in time) {
min = minOf(min, t)
}
var left = 1L
var right = min * totalTrips
while (left <= right) {
val middle = left + (right - left) / 2
val isValid = totalTrips <= getTotalTrips(time, middle)
if (isValid) {
right = middle - 1
} else {
left = middle + 1
}
}
return left
}
private fun getTotalTrips(times: IntArray, requiredTime: Long): Long {
var totalTrips = 0L
for (t in times) {
totalTrips += requiredTime / t.toLong()
}
return totalTrips
}- Time Complexity:
O(n * log m), wherenis the size of thetimearray, andmis the maximum time to complete all trips. - Space Complexity:
O(1).