# 题目描述
礼盒的最大甜蜜度
给你一个正整数数组 price
,其中 price[i]
表示第i
类糖果的价格,另给你一个正整数 k
。
商店组合 k
类 不同 糖果打包成礼盒出售。礼盒的 甜蜜度 是礼盒中任意两种糖果 价格 绝对差的最小值。
返回礼盒的 最大 甜蜜度。
提示
1 <= price.length <= 105
1 <= price[i] <= 109
2 <= k <= price.length
# 测试用例
用例1:
- 输入:
price = [13,5,1,8,21,2], k = 3
- 输出:
8
- 解释:选出价格分别为
[13,5,21]
的三类糖果。礼盒的甜蜜度为min(|13 - 5|, |13 - 21|, |5 - 21|) = min(8, 8, 16) = 8
。 可以证明能够取得的最大甜蜜度就是8
。
用例2:
- 输入:
price = [1,3,1], k = 2
- 输出:
2
- 解释:选出价格分别为
[1,3]
的两类糖果。 礼盒的甜蜜度为min(|1 - 3|) = min(2) = 2
。 可以证明能够取得的最大甜蜜度就是2
。
用例3:
输入:price = [7,7,7,7], k = 2
输出:0
解释:从现有的糖果中任选两类糖果,甜蜜度都会是 0
。
# 思路
参考代码注释
# 代码实现
/**
* @param {number[]} price
* @param {number} k
* @return {number}
*/
/**
输入price和k
*/
var __readline = require("readline-sync");
__readline.setDefaultOptions({ prompt: "" });
var readline = __readline.prompt;
console.log("请输入price数组: ");
let price = readline().split(" ").map(Number);
console.log("请输入k: ");
let k = readline();
var maximumTastiness = function (price, k) {
// 最大最小 —— 要想到二分 —— 二分什么 —— 二分甜蜜值
// 因为选择的差值跟顺序无关,所以可以排序后贪心
// 二分查找时,下边界为0,上边界为price的最大值与最小值之差 —— 因为mid 是甜蜜度,不是下标
// price从小到大排序
price.sort((a, b) => a - b);
let left = 0,
right = price[price.length - 1] - price[0];
while (left < right) {
const mid = Math.floor((left + right + 1) / 2);
if (check(price, k, mid)) {
// mid对应的甜蜜度有可能满足,所以left要取mid
left = mid;
} else {
// mid对应的甜蜜度不满足了,所以right不取mid了
right = mid - 1;
}
}
return left;
};
const check = (price, k, sweet) => {
// 因为第一个值一定要取,比如 3 - 1 > 1, 那4 - 1 一定大于1,所以要定义一个与第一个值相减恒为true的值,
// let prev = -Number.MAX_VALUE / 2;
// 记录大于甜蜜度sweet的个数
let cnt = 0;
let index = 0;
for (let p of price) {
// 大于甜蜜度了,个数 ++,同时,另prev为当前值,开始找下一个大于sweet的区间
// 如果当前值不大于,则遍历下一个值
if (index == 0) {
prev = p;
cnt++;
index = -1;
continue;
}
if (p - prev >= sweet) {
cnt++;
prev = p;
}
// 最后看大于当前sweet的个数是否大于等于k
// 大于等于 —— true,则证明最大甜蜜度应该比传进来的sweet要大,要去二分的右区间继续找
// 小于 —— false,则证明最大甜蜜度比传进来的sweet要小,要去二分的左区间继续找
}
return cnt >= k;
};
let res = maximumTastiness(price, k);
console.log("最大甜蜜度为: ", res);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73