Skip to content

Commit 5fa8727

Browse files
committed
Car fleet
1 parent 5fb8f53 commit 5fa8727

File tree

2 files changed

+240
-0
lines changed

2 files changed

+240
-0
lines changed

853.car_fleet/fleet.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// 853. Car fleet
2+
// Topics: 'Array', 'Sorting', 'Stack', 'Monotonic stack'
3+
// Level: 'Medium'
4+
5+
// There are n cars at given miles away from the starting mile 0, traveling to reach the mile target.
6+
7+
// You are given two integer arrays position and speed, both of length n, where position[i] is the starting mile of the ith car and speed[i] is the speed of the ith car in miles per hour.
8+
9+
// A car cannot pass another car, but it can catch up and then travel next to it at the speed of the slower car.
10+
11+
// A car fleet is a single car or a group of cars driving next to each other. The speed of the car fleet is the minimum speed of any car in the fleet.
12+
13+
// If a car catches up to a car fleet at the mile target, it will still be considered as part of the car fleet.
14+
15+
// Return the number of car fleets that will arrive at the destination.
16+
17+
// Example 1:
18+
19+
// Input: target = 12, position = [10,8,0,5,3], speed = [2,4,1,1,3]
20+
21+
// Output: 3
22+
23+
// Explanation:
24+
25+
// The cars starting at 10 (speed 2) and 8 (speed 4) become a fleet, meeting each other at 12. The fleet forms at target.
26+
// The car starting at 0 (speed 1) does not catch up to any other car, so it is a fleet by itself.
27+
// The cars starting at 5 (speed 1) and 3 (speed 3) become a fleet, meeting each other at 6. The fleet moves at speed 1 until it reaches target.
28+
29+
// Example 2:
30+
31+
// Input: target = 10, position = [3], speed = [3]
32+
33+
// Output: 1
34+
35+
// Explanation:
36+
// There is only one car, hence there is only one fleet.
37+
38+
// Example 3:
39+
40+
// Input: target = 100, position = [0,2,4], speed = [4,2,1]
41+
42+
// Output: 1
43+
44+
// Explanation:
45+
46+
// The cars starting at 0 (speed 4) and 2 (speed 2) become a fleet, meeting each other at 4. The car starting at 4 (speed 1) travels to 5.
47+
// Then, the fleet at 4 (speed 2) and the car at position 5 (speed 1) become one fleet, meeting each other at 6. The fleet moves at speed 1 until it reaches target.
48+
49+
// Constraints:
50+
51+
// n == position.length == speed.length
52+
// 1 <= n <= 105
53+
// 0 < target <= 106
54+
// 0 <= position[i] < target
55+
// All the values of position are unique.
56+
// 0 < speed[i] <= 106
57+
58+
package carfleet
59+
60+
import (
61+
"sort"
62+
)
63+
64+
type cars struct {
65+
ps []int
66+
sp []int
67+
}
68+
69+
func (c *cars) Len() int {
70+
return len(c.ps)
71+
}
72+
73+
func (c *cars) Less(i, j int) bool {
74+
return c.ps[i] > c.ps[j]
75+
}
76+
77+
func (c *cars) Swap(i, j int) {
78+
c.ps[i], c.ps[j] = c.ps[j], c.ps[i]
79+
c.sp[i], c.sp[j] = c.sp[j], c.sp[i]
80+
}
81+
82+
func carFleet(target int, position []int, speed []int) int {
83+
sorted := cars{ps: position, sp: speed}
84+
sort.Sort(&sorted)
85+
cars := []car{newCar(target, sorted.ps[0], sorted.sp[0])}
86+
87+
for i := 1; i < len(sorted.ps); i++ {
88+
car := newCar(target, sorted.ps[i], sorted.sp[i])
89+
if cars[len(cars)-1].t < car.t {
90+
cars = append(cars, car)
91+
}
92+
}
93+
94+
return len(cars)
95+
}
96+
97+
type car struct {
98+
t float64
99+
}
100+
101+
func newCar(target, ps, sp int) car {
102+
timeToTarget := float64(target-ps) / float64(sp)
103+
return car{t: timeToTarget}
104+
}

853.car_fleet/fleet_test.go

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
package carfleet
2+
3+
import "testing"
4+
5+
func TestCarFleet(t *testing.T) {
6+
tests := []struct {
7+
name string
8+
target int
9+
position []int
10+
speed []int
11+
expected int
12+
}{
13+
{
14+
name: "one-by-one",
15+
target: 10,
16+
position: []int{8, 3, 7, 4, 6, 5},
17+
speed: []int{4, 4, 4, 4, 4, 4},
18+
expected: 6,
19+
},
20+
{
21+
name: "Example 1: Multiple fleets form",
22+
target: 12,
23+
position: []int{10, 8, 0, 5, 3},
24+
speed: []int{2, 4, 1, 1, 3},
25+
expected: 3,
26+
},
27+
{
28+
name: "Example 2: Single car",
29+
target: 10,
30+
position: []int{3},
31+
speed: []int{3},
32+
expected: 1,
33+
},
34+
{
35+
name: "Example 3: All cars merge into one fleet",
36+
target: 100,
37+
position: []int{0, 2, 4},
38+
speed: []int{4, 2, 1},
39+
expected: 1,
40+
},
41+
{
42+
name: "Two cars, no merge",
43+
target: 10,
44+
position: []int{0, 5},
45+
speed: []int{1, 1},
46+
expected: 2,
47+
},
48+
{
49+
name: "Two cars merge into one fleet",
50+
target: 10,
51+
position: []int{0, 5},
52+
speed: []int{2, 1},
53+
expected: 1,
54+
},
55+
{
56+
name: "Car already at target",
57+
target: 10,
58+
position: []int{9},
59+
speed: []int{1},
60+
expected: 1,
61+
},
62+
{
63+
name: "All cars at different positions, same speed",
64+
target: 10,
65+
position: []int{1, 3, 5, 7},
66+
speed: []int{1, 1, 1, 1},
67+
expected: 4,
68+
},
69+
{
70+
name: "Cars with varying speeds, closer car is faster",
71+
target: 10,
72+
position: []int{8, 6, 4},
73+
speed: []int{1, 2, 3},
74+
expected: 1,
75+
},
76+
{
77+
name: "Fast car catches slow car exactly at target",
78+
target: 12,
79+
position: []int{10, 8},
80+
speed: []int{2, 4},
81+
expected: 1,
82+
},
83+
{
84+
name: "Large target with close cars",
85+
target: 1000000,
86+
position: []int{999999, 999998},
87+
speed: []int{1, 1},
88+
expected: 2,
89+
},
90+
{
91+
name: "Three separate fleets",
92+
target: 10,
93+
position: []int{0, 3, 5, 8},
94+
speed: []int{1, 1, 1, 1},
95+
expected: 4,
96+
},
97+
{
98+
name: "Cars with high speeds",
99+
target: 100,
100+
position: []int{10, 20, 30},
101+
speed: []int{1000000, 1000000, 1000000},
102+
expected: 3,
103+
},
104+
{
105+
name: "Edge case: car at position 0",
106+
target: 10,
107+
position: []int{0},
108+
speed: []int{5},
109+
expected: 1,
110+
},
111+
{
112+
name: "Slower car ahead catches faster car behind",
113+
target: 10,
114+
position: []int{5, 2},
115+
speed: []int{1, 5},
116+
expected: 1,
117+
},
118+
{
119+
name: "Random order positions",
120+
target: 10,
121+
position: []int{6, 2, 8, 4},
122+
speed: []int{2, 3, 1, 4},
123+
expected: 2,
124+
},
125+
}
126+
127+
for _, tt := range tests {
128+
t.Run(tt.name, func(t *testing.T) {
129+
result := carFleet(tt.target, tt.position, tt.speed)
130+
if result != tt.expected {
131+
t.Errorf("carFleet(%d, %v, %v) = %d; expected %d",
132+
tt.target, tt.position, tt.speed, result, tt.expected)
133+
}
134+
})
135+
}
136+
}

0 commit comments

Comments
 (0)