Skip to content

Commit f3d39a1

Browse files
committed
feat: leetcode 857
1 parent ba31a60 commit f3d39a1

File tree

10 files changed

+172
-1
lines changed

10 files changed

+172
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<p align="center">
44
<!-- TOPICS COUNT START -->
5-
<img src="https://img.shields.io/badge/-进度:490-green" alt="进度:490">
5+
<img src="https://img.shields.io/badge/-进度:491-green" alt="进度:491">
66
<!-- TOPICS COUNT END -->
77
<a href="./assets/docs/TOPICS.md"><img src="https://img.shields.io/badge/-题库目录-blue" alt="题库目录"></a>
88
<a href="./assets/docs/CATEGORIES.md"><img src="https://img.shields.io/badge/-题库分类-red" alt="题库分类"></a>

assets/data/categories.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3502,6 +3502,12 @@
35023502
"path": "./problemset/set-intersection-size-at-least-two/README.md",
35033503
"difficulty": "困难"
35043504
},
3505+
{
3506+
"id": "857",
3507+
"title": "雇佣 K 名工人的最低成本",
3508+
"path": "./problemset/minimum-cost-to-hire-k-workers/README.md",
3509+
"difficulty": "困难"
3510+
},
35053511
{
35063512
"id": "871",
35073513
"title": "最低加油次数",
@@ -4174,6 +4180,12 @@
41744180
"path": "./problemset/find-median-from-data-stream/README.md",
41754181
"difficulty": "困难"
41764182
},
4183+
{
4184+
"id": "857",
4185+
"title": "雇佣 K 名工人的最低成本",
4186+
"path": "./problemset/minimum-cost-to-hire-k-workers/README.md",
4187+
"difficulty": "困难"
4188+
},
41774189
{
41784190
"id": "1606",
41794191
"title": "找到处理最多请求的服务器",

assets/data/topics.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3849,6 +3849,16 @@
38493849
"url": "https://leetcode-cn.com/problems/push-dominoes/",
38503850
"path": "./problemset/push-dominoes/README.md"
38513851
},
3852+
{
3853+
"id": "857",
3854+
"title": {
3855+
"cn": "雇佣 K 名工人的最低成本",
3856+
"en": "minimum-cost-to-hire-k-workers"
3857+
},
3858+
"difficulty": "困难",
3859+
"url": "https://leetcode.cn/problems/minimum-cost-to-hire-k-workers/",
3860+
"path": "./problemset/minimum-cost-to-hire-k-workers/README.md"
3861+
},
38523862
{
38533863
"id": "868",
38543864
"title": {

assets/docs/CATEGORIES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,7 @@
654654
| 334. [递增的三元子序列](../../problemset/increasing-triplet-subsequence/README.md) | 中等 |
655655
| 646. [最长数对链](../../problemset/maximum-length-of-pair-chain/README.md) | 中等 |
656656
| 757. [设置交集大小至少为2](../../problemset/set-intersection-size-at-least-two/README.md) | 困难 |
657+
| 857. [雇佣 K 名工人的最低成本](../../problemset/minimum-cost-to-hire-k-workers/README.md) | 困难 |
657658
| 871. [最低加油次数](../../problemset/minimum-number-of-refueling-stops/README.md) | 困难 |
658659
| 942. [增减字符串匹配](../../problemset/di-string-match/README.md) | 简单 |
659660
| 1217. [玩筹码](../../problemset/minimum-cost-to-move-chips-to-the-same-position/README.md) | 简单 |
@@ -791,6 +792,7 @@
791792
| 239. [滑动窗口最大值](../../problemset/sliding-window-maximum/README.md) | 困难 |
792793
| 264. [丑数 II](../../problemset/ugly-number-2/README.md) | 中等 |
793794
| 295. [数据流的中位数](../../problemset/find-median-from-data-stream/README.md) | 困难 |
795+
| 857. [雇佣 K 名工人的最低成本](../../problemset/minimum-cost-to-hire-k-workers/README.md) | 困难 |
794796
| 1606. [找到处理最多请求的服务器](../../problemset/find-servers-that-handled-most-number-of-requests/README.md) | 困难 |
795797

796798
## 树状数组

assets/docs/TOPICS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,8 @@
770770

771771
[838. 推多米诺](../../problemset/push-dominoes/README.md)
772772

773+
[857. 雇佣 K 名工人的最低成本](../../problemset/minimum-cost-to-hire-k-workers/README.md)
774+
773775
[868. 二进制间距](../../problemset/binary-gap/README.md)
774776

775777
[871. 最低加油次数](../../problemset/minimum-number-of-refueling-stops/README.md)

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,8 @@
3131
"typescript": "^4.6.3",
3232
"vite": "^2.9.5",
3333
"vitest": "^0.9.4"
34+
},
35+
"dependencies": {
36+
"@datastructures-js/priority-queue": "^6.1.3"
3437
}
3538
}

pnpm-lock.yaml

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# 雇佣 K 名工人的最低成本
2+
3+
> 难度:困难
4+
>
5+
> https://leetcode.cn/problems/minimum-cost-to-hire-k-workers/
6+
7+
## 题目
8+
9+
`n` 名工人。 给定两个数组 `quality` 和 `wage` ,其中,`quality[i]` 表示第 `i` 名工人的工作质量,其最低期望工资为 `wage[i]` 。
10+
11+
现在我们想雇佣 `k` 名工人组成一个工资组。在雇佣 一组 `k` 名工人时,我们必须按照下述规则向他们支付工资:
12+
13+
1. 对工资组中的每名工人,应当按其工作质量与同组其他工人的工作质量的比例来支付工资。
14+
2. 工资组中的每名工人至少应当得到他们的最低期望工资。
15+
16+
给定整数 `k` ,返回 组成满足上述条件的付费群体所需的最小金额 。在实际答案的 `10^-5` 以内的答案将被接受。
17+
18+
### 示例
19+
20+
#### 示例 1:
21+
22+
```
23+
输入: quality = [10,20,5], wage = [70,50,30], k = 2
24+
输出: 105.00000
25+
解释: 我们向 0 号工人支付 70,向 2 号工人支付 35。
26+
```
27+
28+
#### 示例 2:
29+
30+
```
31+
输入: quality = [3,1,10,10,1], wage = [4,8,2,2,7], k = 3
32+
输出: 30.66667
33+
解释: 我们向 0 号工人支付 4,向 2 号和 3 号分别支付 13.33333。
34+
```
35+
36+
## 解题
37+
38+
```ts
39+
/**
40+
* 贪心 + 优先队列
41+
* @desc 时间复杂度 O(NlogN) 空间复杂度 O(N)
42+
* @param quality
43+
* @param wage
44+
* @param k
45+
* @returns
46+
*/
47+
export function mincostToHireWorkers(quality: number[], wage: number[], k: number): number {
48+
const n = quality.length
49+
const h = new Array(n).fill(0).map((_, i) => i)
50+
h.sort((a, b) => {
51+
return quality[b] * wage[a] - quality[a] * wage[b]
52+
})
53+
let res = 1e9
54+
let totalq = 0.0
55+
const pq = new MaxPriorityQueue<number>()
56+
for (let i = 0; i < k - 1; i++) {
57+
totalq += quality[h[i]]
58+
pq.enqueue(quality[h[i]])
59+
}
60+
for (let i = k - 1; i < n; i++) {
61+
const idx = h[i]
62+
totalq += quality[idx]
63+
pq.enqueue(quality[idx])
64+
const totalc = (wage[idx] / quality[idx]) * totalq
65+
res = Math.min(res, totalc)
66+
totalq -= pq.dequeue()
67+
}
68+
return Number(res.toFixed(5))
69+
}
70+
```
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { mincostToHireWorkers } from '.'
3+
4+
describe('雇佣 K 名工人的最低成本', () => {
5+
testCase(mincostToHireWorkers)
6+
})
7+
8+
function testCase(fn: (quality: number[], wage: number[], k: number) => number) {
9+
it.each([
10+
[
11+
[10, 20, 5],
12+
[70, 50, 30],
13+
2,
14+
105,
15+
],
16+
[
17+
[3, 1, 10, 10, 1],
18+
[4, 8, 2, 2, 7],
19+
3,
20+
30.66667,
21+
],
22+
])('示例%#', (quality, wage, k, expected) => {
23+
expect(fn(quality, wage, k)).toBe(expected)
24+
})
25+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { MaxPriorityQueue } from '@datastructures-js/priority-queue'
2+
3+
/**
4+
* 贪心 + 优先队列
5+
* @desc 时间复杂度 O(NlogN) 空间复杂度 O(N)
6+
* @param quality
7+
* @param wage
8+
* @param k
9+
* @returns
10+
*/
11+
export function mincostToHireWorkers(quality: number[], wage: number[], k: number): number {
12+
const n = quality.length
13+
const h = new Array(n).fill(0).map((_, i) => i)
14+
h.sort((a, b) => {
15+
return quality[b] * wage[a] - quality[a] * wage[b]
16+
})
17+
let res = 1e9
18+
let totalq = 0.0
19+
const pq = new MaxPriorityQueue<number>()
20+
for (let i = 0; i < k - 1; i++) {
21+
totalq += quality[h[i]]
22+
pq.enqueue(quality[h[i]])
23+
}
24+
for (let i = k - 1; i < n; i++) {
25+
const idx = h[i]
26+
totalq += quality[idx]
27+
pq.enqueue(quality[idx])
28+
const totalc = (wage[idx] / quality[idx]) * totalq
29+
res = Math.min(res, totalc)
30+
totalq -= pq.dequeue()
31+
}
32+
return Number(res.toFixed(5))
33+
}

0 commit comments

Comments
 (0)