Skip to content

Commit b2ef4af

Browse files
authored
Create 2462-total-cost-to-hire-k-workers.js
1 parent 9df567c commit b2ef4af

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed

2462-total-cost-to-hire-k-workers.js

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/**
2+
* @param {number[]} costs
3+
* @param {number} k
4+
* @param {number} candidates
5+
* @return {number}
6+
*/
7+
const totalCost = function(costs, k, candidates) {
8+
const fn = (a, b) => a[0] === b[0] ? a[1] < b[1] : a[0] < b[0]
9+
const n = costs.length
10+
let l = 0, r = n - 1
11+
const first = new PriorityQueue(fn)
12+
const last = new PriorityQueue(fn)
13+
14+
for(let i = 0; i < Math.min(candidates, n); i++) {
15+
first.push([costs[i], i])
16+
l = i
17+
}
18+
19+
for(let i = n - 1; i > Math.max(0, candidates - 1, n - 1 - candidates); i--) {
20+
last.push([costs[i], i])
21+
r = i
22+
}
23+
24+
// console.log(first, last)
25+
26+
let res = 0
27+
let num = k
28+
while(num) {
29+
const ft = first.peek()
30+
const lt = last.peek()
31+
32+
if(ft && lt) {
33+
if(ft[0] < lt[0]) {
34+
first.pop()
35+
res += ft[0]
36+
if(r - l > 1) {
37+
l++
38+
first.push([costs[l], l])
39+
}
40+
} else if(ft[0] > lt[0]) {
41+
last.pop()
42+
res += lt[0]
43+
if(r - l > 1) {
44+
r--
45+
last.push([costs[r], r])
46+
}
47+
} else {
48+
first.pop()
49+
res += ft[0]
50+
if(r - l > 1) {
51+
l++
52+
first.push([costs[l], l])
53+
}
54+
}
55+
} else if(ft) {
56+
first.pop()
57+
res += ft[0]
58+
} else if(lt) {
59+
last.pop()
60+
res += lt[0]
61+
}
62+
// console.log(res)
63+
num--
64+
}
65+
66+
67+
return res
68+
69+
};
70+
71+
72+
class PriorityQueue {
73+
constructor(comparator = (a, b) => a > b) {
74+
this.heap = []
75+
this.top = 0
76+
this.comparator = comparator
77+
}
78+
size() {
79+
return this.heap.length
80+
}
81+
isEmpty() {
82+
return this.size() === 0
83+
}
84+
peek() {
85+
return this.heap[this.top]
86+
}
87+
push(...values) {
88+
values.forEach((value) => {
89+
this.heap.push(value)
90+
this.siftUp()
91+
})
92+
return this.size()
93+
}
94+
pop() {
95+
const poppedValue = this.peek()
96+
const bottom = this.size() - 1
97+
if (bottom > this.top) {
98+
this.swap(this.top, bottom)
99+
}
100+
this.heap.pop()
101+
this.siftDown()
102+
return poppedValue
103+
}
104+
replace(value) {
105+
const replacedValue = this.peek()
106+
this.heap[this.top] = value
107+
this.siftDown()
108+
return replacedValue
109+
}
110+
111+
parent = (i) => ((i + 1) >>> 1) - 1
112+
left = (i) => (i << 1) + 1
113+
right = (i) => (i + 1) << 1
114+
greater = (i, j) => this.comparator(this.heap[i], this.heap[j])
115+
swap = (i, j) => ([this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]])
116+
siftUp = () => {
117+
let node = this.size() - 1
118+
while (node > this.top && this.greater(node, this.parent(node))) {
119+
this.swap(node, this.parent(node))
120+
node = this.parent(node)
121+
}
122+
}
123+
siftDown = () => {
124+
let node = this.top
125+
while (
126+
(this.left(node) < this.size() && this.greater(this.left(node), node)) ||
127+
(this.right(node) < this.size() && this.greater(this.right(node), node))
128+
) {
129+
let maxChild =
130+
this.right(node) < this.size() &&
131+
this.greater(this.right(node), this.left(node))
132+
? this.right(node)
133+
: this.left(node)
134+
this.swap(node, maxChild)
135+
node = maxChild
136+
}
137+
}
138+
}

0 commit comments

Comments
 (0)