Minimum Speed to Arrive on Time

medium binary search

Problem

Given dist[] of leg lengths and a deadline `hour`, return the minimum integer speed that lets you finish in time. Every leg except the last must round up its travel time.

Inputdist = [1,3,2], hour = 6
Output1
Speed 1: ceil(1)+ceil(3)+2 = 6.

def min_speed_on_time(dist, hour):
    n = len(dist)
    if hour <= n - 1: return -1
    def ok(v):
        t = 0.0
        for i in range(n - 1):
            t += -(-dist[i] // v)  # ceil
        t += dist[-1] / v
        return t <= hour
    lo, hi = 1, 10**7
    if not ok(hi): return -1
    while lo < hi:
        mid = (lo + hi) // 2
        if ok(mid): hi = mid
        else: lo = mid + 1
    return lo
function minSpeedOnTime(dist, hour) {
  const n = dist.length;
  if (hour <= n - 1) return -1;
  function ok(v) {
    let t = 0;
    for (let i = 0; i < n - 1; i++) t += Math.ceil(dist[i] / v);
    t += dist[n - 1] / v;
    return t <= hour;
  }
  let lo = 1, hi = 1e7;
  if (!ok(hi)) return -1;
  while (lo < hi) {
    const mid = Math.floor((lo + hi) / 2);
    if (ok(mid)) hi = mid; else lo = mid + 1;
  }
  return lo;
}
class Solution {
    public int minSpeedOnTime(int[] dist, double hour) {
        int n = dist.length;
        if (hour <= n - 1) return -1;
        int lo = 1, hi = 10000000;
        while (lo < hi) {
            int mid = (lo + hi) >>> 1;
            double t = 0;
            for (int i = 0; i < n - 1; i++) t += (dist[i] + mid - 1) / mid;
            t += (double) dist[n - 1] / mid;
            if (t <= hour) hi = mid; else lo = mid + 1;
        }
        double t = 0;
        for (int i = 0; i < n - 1; i++) t += (dist[i] + lo - 1) / lo;
        t += (double) dist[n - 1] / lo;
        return t <= hour ? lo : -1;
    }
}
int minSpeedOnTime(vector<int>& dist, double hour) {
    int n = dist.size();
    if (hour <= n - 1) return -1;
    int lo = 1, hi = 10000000;
    while (lo < hi) {
        int mid = (lo + hi) / 2;
        double t = 0;
        for (int i = 0; i < n - 1; i++) t += (dist[i] + mid - 1) / mid;
        t += (double) dist[n - 1] / mid;
        if (t <= hour) hi = mid; else lo = mid + 1;
    }
    double t = 0;
    for (int i = 0; i < n - 1; i++) t += (dist[i] + lo - 1) / lo;
    t += (double) dist[n - 1] / lo;
    return t <= hour ? lo : -1;
}
Time: O(n log V) Space: O(1)