comments | difficulty | edit_url | rating | source | tags | ||
---|---|---|---|---|---|---|---|
true |
中等 |
1675 |
第 242 场周赛 Q2 |
|
给你一个浮点数 hour
,表示你到达办公室可用的总通勤时间。要到达办公室,你必须按给定次序乘坐 n
趟列车。另给你一个长度为 n
的整数数组 dist
,其中 dist[i]
表示第 i
趟列车的行驶距离(单位是千米)。
每趟列车均只能在整点发车,所以你可能需要在两趟列车之间等待一段时间。
- 例如,第
1
趟列车需要1.5
小时,那你必须再等待0.5
小时,搭乘在第 2 小时发车的第2
趟列车。
返回能满足你准时到达办公室所要求全部列车的 最小正整数 时速(单位:千米每小时),如果无法准时到达,则返回 -1
。
生成的测试用例保证答案不超过 107
,且 hour
的 小数点后最多存在两位数字 。
示例 1:
输入:dist = [1,3,2], hour = 6 输出:1 解释:速度为 1 时: - 第 1 趟列车运行需要 1/1 = 1 小时。 - 由于是在整数时间到达,可以立即换乘在第 1 小时发车的列车。第 2 趟列车运行需要 3/1 = 3 小时。 - 由于是在整数时间到达,可以立即换乘在第 4 小时发车的列车。第 3 趟列车运行需要 2/1 = 2 小时。 - 你将会恰好在第 6 小时到达。
示例 2:
输入:dist = [1,3,2], hour = 2.7 输出:3 解释:速度为 3 时: - 第 1 趟列车运行需要 1/3 = 0.33333 小时。 - 由于不是在整数时间到达,故需要等待至第 1 小时才能搭乘列车。第 2 趟列车运行需要 3/3 = 1 小时。 - 由于是在整数时间到达,可以立即换乘在第 2 小时发车的列车。第 3 趟列车运行需要 2/3 = 0.66667 小时。 - 你将会在第 2.66667 小时到达。
示例 3:
输入:dist = [1,3,2], hour = 1.9 输出:-1 解释:不可能准时到达,因为第 3 趟列车最早是在第 2 小时发车。
提示:
n == dist.length
1 <= n <= 105
1 <= dist[i] <= 105
1 <= hour <= 109
hours
中,小数点后最多存在两位数字
我们注意到,如果一个速度值
在二分查找之前,我们需要先判断是否有可能在规定时间内到达。如果列车数量大于向上取整的规定时间,那么一定无法在规定时间内到达,直接返回
接下来,我们定义二分的左右边界为
问题转化为判断一个速度值
二分结束后,如果左边界超过了
时间复杂度
class Solution:
def minSpeedOnTime(self, dist: List[int], hour: float) -> int:
def check(v: int) -> bool:
s = 0
for i, d in enumerate(dist):
t = d / v
s += t if i == len(dist) - 1 else ceil(t)
return s <= hour
if len(dist) > ceil(hour):
return -1
r = 10**7 + 1
ans = bisect_left(range(1, r), True, key=check) + 1
return -1 if ans == r else ans
class Solution {
public int minSpeedOnTime(int[] dist, double hour) {
if (dist.length > Math.ceil(hour)) {
return -1;
}
final int m = (int) 1e7;
int l = 1, r = m + 1;
while (l < r) {
int mid = (l + r) >> 1;
if (check(dist, mid, hour)) {
r = mid;
} else {
l = mid + 1;
}
}
return l > m ? -1 : l;
}
private boolean check(int[] dist, int v, double hour) {
double s = 0;
int n = dist.length;
for (int i = 0; i < n; ++i) {
double t = dist[i] * 1.0 / v;
s += i == n - 1 ? t : Math.ceil(t);
}
return s <= hour;
}
}
class Solution {
public:
int minSpeedOnTime(vector<int>& dist, double hour) {
if (dist.size() > ceil(hour)) {
return -1;
}
const int m = 1e7;
int l = 1, r = m + 1;
int n = dist.size();
auto check = [&](int v) {
double s = 0;
for (int i = 0; i < n; ++i) {
double t = dist[i] * 1.0 / v;
s += i == n - 1 ? t : ceil(t);
}
return s <= hour;
};
while (l < r) {
int mid = (l + r) >> 1;
if (check(mid)) {
r = mid;
} else {
l = mid + 1;
}
}
return l > m ? -1 : l;
}
};
func minSpeedOnTime(dist []int, hour float64) int {
if float64(len(dist)) > math.Ceil(hour) {
return -1
}
const m int = 1e7
n := len(dist)
ans := sort.Search(m+1, func(v int) bool {
v++
s := 0.0
for i, d := range dist {
t := float64(d) / float64(v)
if i == n-1 {
s += t
} else {
s += math.Ceil(t)
}
}
return s <= hour
}) + 1
if ans > m {
return -1
}
return ans
}
function minSpeedOnTime(dist: number[], hour: number): number {
if (dist.length > Math.ceil(hour)) {
return -1;
}
const n = dist.length;
const m = 10 ** 7;
const check = (v: number): boolean => {
let s = 0;
for (let i = 0; i < n; ++i) {
const t = dist[i] / v;
s += i === n - 1 ? t : Math.ceil(t);
}
return s <= hour;
};
let [l, r] = [1, m + 1];
while (l < r) {
const mid = (l + r) >> 1;
if (check(mid)) {
r = mid;
} else {
l = mid + 1;
}
}
return l > m ? -1 : l;
}
impl Solution {
pub fn min_speed_on_time(dist: Vec<i32>, hour: f64) -> i32 {
if dist.len() as f64 > hour.ceil() {
return -1;
}
const M: i32 = 10_000_000;
let (mut l, mut r) = (1, M + 1);
let n = dist.len();
let check = |v: i32| -> bool {
let mut s = 0.0;
for i in 0..n {
let t = dist[i] as f64 / v as f64;
s += if i == n - 1 { t } else { t.ceil() };
}
s <= hour
};
while l < r {
let mid = (l + r) / 2;
if check(mid) {
r = mid;
} else {
l = mid + 1;
}
}
if l > M {
-1
} else {
l
}
}
}
/**
* @param {number[]} dist
* @param {number} hour
* @return {number}
*/
var minSpeedOnTime = function (dist, hour) {
if (dist.length > Math.ceil(hour)) {
return -1;
}
const n = dist.length;
const m = 10 ** 7;
const check = v => {
let s = 0;
for (let i = 0; i < n; ++i) {
const t = dist[i] / v;
s += i === n - 1 ? t : Math.ceil(t);
}
return s <= hour;
};
let [l, r] = [1, m + 1];
while (l < r) {
const mid = (l + r) >> 1;
if (check(mid)) {
r = mid;
} else {
l = mid + 1;
}
}
return l > m ? -1 : l;
};
class Solution {
fun minSpeedOnTime(dist: IntArray, hour: Double): Int {
val n = dist.size
if (n > Math.ceil(hour)) {
return -1
}
val m = 1e7.toInt()
var left = 1
var right = m + 1
while (left < right) {
val middle = (left + right) / 2
var time = 0.0
dist.forEachIndexed { i, item ->
val t = item.toDouble() / middle
time += if (i == n - 1) t else Math.ceil(t)
}
if (time > hour) {
left = middle + 1
} else {
right = middle
}
}
return if (left > m) -1 else left
}
}