Skip to content

Commit 42fad59

Browse files
committed
added problem 2462
1 parent b06405b commit 42fad59

File tree

3 files changed

+139
-0
lines changed

3 files changed

+139
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package problem2462
2+
3+
import (
4+
"container/heap"
5+
)
6+
7+
/*
8+
You are given a 0-indexed integer array costs where costs[i] is the cost of hiring the ith worker.
9+
You are also given two integers k and candidates. We want to hire exactly k workers according to the following rules:
10+
You will run k sessions and hire exactly one worker in each session.
11+
In each hiring session, choose the worker with the lowest cost from either the first candidates workers or the last candidates workers.
12+
Break the tie by the smallest index.
13+
For example, if costs = [3,2,7,7,1,2] and candidates = 2, then in the first hiring session,
14+
we will choose the 4th worker because they have the lowest cost [3,2,7,7,1,2].
15+
In the second hiring session, we will choose 1st worker because they have the same lowest cost as
16+
4th worker but they have the smallest index [3,2,7,7,2].
17+
Please note that the indexing may be changed in the process.
18+
If there are fewer than candidates workers remaining, choose the worker with the lowest cost among them. Break the tie by the smallest index.
19+
A worker can only be chosen once.
20+
Return the total cost to hire exactly k workers.
21+
*/
22+
23+
func totalCost(costs []int, k, candidates int) int64 {
24+
var res int64
25+
26+
if len(costs) == 1 {
27+
return int64(costs[0])
28+
}
29+
30+
// left and right represent the inner index of the left and right groups
31+
left, right := 0, len(costs)-1
32+
33+
// lPq and rPq are priority que
34+
lPq, rPq := MakeHeap(MinHeap), MakeHeap(MinHeap)
35+
for i := 0; i < candidates && right > left; i++ {
36+
heap.Push(lPq, costs[i])
37+
heap.Push(rPq, costs[len(costs)-i-1])
38+
left++
39+
right--
40+
}
41+
42+
for ; k > 0; k-- {
43+
if lPq.Len() == 0 {
44+
// If left is empty, take from right
45+
res += int64(heap.Pop(rPq).(int))
46+
continue
47+
} else if rPq.Len() == 0 {
48+
// If right is empty, take from left
49+
res += int64(heap.Pop(lPq).(int))
50+
continue
51+
}
52+
53+
lTemp, rTemp := lPq.Peek(), rPq.Peek()
54+
if rTemp < lTemp {
55+
// Take from right
56+
res += int64(heap.Pop(rPq).(int))
57+
if right >= left {
58+
// Only push if the groups aren't colliding
59+
heap.Push(rPq, costs[right])
60+
right--
61+
}
62+
} else {
63+
// Take from left
64+
res += int64(heap.Pop(lPq).(int))
65+
if right >= left {
66+
// Only push if the groups aren't colliding
67+
heap.Push(lPq, costs[left])
68+
left++
69+
}
70+
}
71+
}
72+
73+
return res
74+
}
75+
76+
// Priority queue implementation
77+
type Heap struct {
78+
Values []int
79+
LessFunc func(int, int) bool
80+
}
81+
82+
func (h *Heap) Less(i, j int) bool { return h.LessFunc(h.Values[i], h.Values[j]) }
83+
func (h *Heap) Swap(i, j int) { h.Values[i], h.Values[j] = h.Values[j], h.Values[i] }
84+
func (h *Heap) Len() int { return len(h.Values) }
85+
func (h *Heap) Peek() int { return h.Values[0] }
86+
func (h *Heap) Pop() (v interface{}) {
87+
h.Values, v = h.Values[:h.Len()-1], h.Values[h.Len()-1]
88+
return v
89+
}
90+
func (h *Heap) Push(v interface{}) { h.Values = append(h.Values, v.(int)) }
91+
92+
func MakeHeap(less func(int, int) bool) *Heap {
93+
return &Heap{LessFunc: less}
94+
}
95+
96+
func MaxHeap(i, j int) bool { return i > j }
97+
func MinHeap(i, j int) bool { return i < j }
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package problem2462
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
type TestCase struct {
11+
Cost []int
12+
K, Candidate int
13+
Expected int64
14+
}
15+
16+
var TestCases = []TestCase{
17+
{[]int{48}, 1, 1, 48},
18+
{[]int{20, 10}, 2, 2, 30},
19+
{[]int{30, 20, 10}, 3, 3, 60},
20+
{[]int{17, 12, 10, 2, 7, 2, 11, 20, 8}, 3, 9, 11},
21+
{[]int{1, 2, 4, 1}, 3, 3, 4},
22+
{[]int{57, 33, 26, 76, 14, 67, 24, 90, 72, 37, 30}, 11, 2, 526},
23+
}
24+
25+
func TestTotalCostToHire(t *testing.T) {
26+
assert := assert.New(t)
27+
28+
for _, tc := range TestCases {
29+
want := tc.Expected
30+
got := totalCost(tc.Cost, tc.K, tc.Candidate)
31+
assert.Equal(want, got, fmt.Sprintf("%+v", tc))
32+
}
33+
}
34+
35+
func BenchmarkTotalCostToHire(b *testing.B) {
36+
for i := 0; i < b.N; i++ {
37+
for _, tc := range TestCases {
38+
totalCost(tc.Cost, tc.K, tc.Candidate)
39+
}
40+
}
41+
}

readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,7 @@ Each problem is in it's own directory, with test files. There are helper package
520520
| 2439 | [Minimize Maximum of Array](https://leetcode.com/problems/minimize-maximum-of-array) | [My Solution](./problems/problem2439) ||
521521
| 2444 | [Count Subarrays With Fixed Bounds](https://leetcode.com/problems/count-subarrays-with-fixed-bounds) | [My Solution](./problems/problem2444) ||
522522
| 2448 | [Minimum Cost to Make Array Equal](https://leetcode.com/problems/minimum-cost-to-make-array-equal) | [My Solution](./problems/problem2448) ||
523+
| 2462 | [Total Cost to Hire K Workers](https://leetcode.com/problems/total-cost-to-hire-k-workers) | [My Solution](./problems/problem2462) ||
523524
| 2466 | [Count Ways To Build Good Strings](https://leetcode.com/problems/count-ways-to-build-good-strings) | [My Solution](./problems/problem2466) ||
524525
| 2477 | [Minimum Fuel Cost to Report to the Capital](https://leetcode.com/problems/minimum-fuel-cost-to-report-to-the-capital) | [My Solution](./problems/problem2477) ||
525526
| 2492 | [Minimum Score of a Path Between Two Cities](https://leetcode.com/problems/minimum-score-of-a-path-between-two-cities) | [My Solution](./problems/problem2492) ||

0 commit comments

Comments
 (0)