题目
-
概述:N辆车沿着一条车道驶向位于target英里之外的共同目的地,每辆车i以恒定的速度speed[i]从初始位置position[i]沿车道驶向目的地,当一辆车追上前一车队时,它的速度会与前一辆车相同,且这辆车和前一辆车构成一个车队(一辆车也是一个车队),问会有多少车队到达目的地
到目的地的一瞬间才赶上前一辆车也构成一个车队
-
输入:
- target:终点位置,范围[0, 10^6]
- position数组:车的初始位置(各不相同,且都是小于target的自然数)
- speed数组:车的速度,速度范围(0, 10^6]
- 车的数量[0, 10^4]
-
输出:到达目的地时的车队数量
思路
-
由于需要暂存初始位置离终点较远的车辆信息以判断之后能否追上与初始位置离终点较近的车辆,所以考虑用栈实现
-
将车辆按照初始位置进行排序
-
将第一辆车入栈
-
遍历之后的车辆,若栈顶车队不能在终点前追上当前车辆,则将当前车辆入栈 -
遍历之后的车辆:
- 若栈顶车队不能在终点前追上当前车辆,则将当前车辆入栈
- 若栈顶车队能在终点前追上当前车辆,栈顶车队出栈,若此时栈为空,则将当前车辆入栈,否则重复
-
最终栈中的车辆个数即为达到目的地时的车队数量
特别注意:两个int型相乘可能会溢出,要将其中一个int型强转为long型,而不是乘完再强转就已经溢出了
代码
class Solution {
public int carFleet(int target, int[] position, int[] speed) {
if (position.length == 0) {
return 0;
}
Car[] cars = new Car[position.length];
for (int i = 0; i < position.length; ++i) {
cars[i] = new Car(position[i], speed[i]);
}
Arrays.sort(cars, (car1, car2) -> car1.position - car2.position);
LinkedList<Car> stack = new LinkedList<>();
stack.push(cars[0]);
for (int i = 1; i < position.length; ++i) {
while (true) {
if (stack.peek().slower(cars[i], target)) {
stack.push(cars[i]);
break;
} else {
stack.pop();
if (stack.isEmpty()) {
stack.push(cars[i]);
break;
}
}
}
}
return stack.size();
}
private class Car {
int position;
int speed;
Car(int position, int speed) {
this.position = position;
this.speed = speed;
}
boolean slower(Car car, int target) {
if (car.speed >= speed) {
return true;
} else {
// strong rotation one, not both
return (long)(car.position - position) * car.speed > (long)(target - car.position) * (speed - car.speed);
}
}
}
}
网友评论