LeetCode 题解工作台

礼盒的最大甜蜜度

给你一个正整数数组 price ,其中 price[i] 表示第 i 类糖果的价格,另给你一个正整数 k 。 商店组合 k 类 不同 糖果打包成礼盒出售。礼盒的 甜蜜度 是礼盒中任意两种糖果 价格 绝对差的最小值。 返回礼盒的 最大 甜蜜度 。 示例 1: 输入: price = [13,5,1,8…

category

4

题型

code_blocks

6

代码语言

hub

3

相关题

当前训练重点

中等 · 二分·搜索·答案·空间

bolt

答案摘要

我们注意到,如果一个甜蜜度为 的礼盒是可行的,那么甜蜜度小于 的礼盒也是可行的,这存在着单调性,因此我们可以使用二分查找的方法,找到最大的可行甜蜜度。 我们首先将数组 排序,然后定义二分查找的左边界 , 。每一次,我们计算出当前的中间值 $mid = \lfloor \frac{l+r+1}{2} \rfloor$,以 作为甜蜜度,判断是否可行。若可行,那么我们将左边界 更新为 ,否则将…

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 二分·搜索·答案·空间 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给你一个正整数数组 price ,其中 price[i] 表示第 i 类糖果的价格,另给你一个正整数 k

商店组合 k不同 糖果打包成礼盒出售。礼盒的 甜蜜度 是礼盒中任意两种糖果 价格 绝对差的最小值。

返回礼盒的 最大 甜蜜度

 

示例 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 。

 

提示:

  • 2 <= k <= price.length <= 105
  • 1 <= price[i] <= 109
lightbulb

解题思路

方法一:贪心 + 二分查找

我们注意到,如果一个甜蜜度为 xx 的礼盒是可行的,那么甜蜜度小于 xx 的礼盒也是可行的,这存在着单调性,因此我们可以使用二分查找的方法,找到最大的可行甜蜜度。

我们首先将数组 priceprice 排序,然后定义二分查找的左边界 l=0l=0, r=price[n1]price[0]r=price[n-1]-price[0]。每一次,我们计算出当前的中间值 mid=l+r+12mid = \lfloor \frac{l+r+1}{2} \rfloor,以 midmid 作为甜蜜度,判断是否可行。若可行,那么我们将左边界 ll 更新为 midmid,否则将右边界 rr 更新为 mid1mid-1。最后返回 ll 即可。

那么问题的关键转化为:判断一个甜蜜度是否可行,我们通过函数 check(x)check(x) 来实现。函数 check(x)check(x) 的执行逻辑如下:

定义一个变量 cntcnt 表示当前已经选取的糖果的数量,初始值为 00,定义一个变量 prepre 表示上一个选取的糖果的价格,初始值为 x-x。然后我们遍历排好序的数组 priceprice,对于每一个糖果的价格 curcur,如果 curprexcur-pre \geq x,那么我们就选取这个糖果,将 prepre 更新为 curcur,并将 cntcnt 加一。最后判断 cntcnt 是否大于等于 kk,如果是,那么返回 truetrue,否则返回 falsefalse

时间复杂度 O(n×(logn+logM))O(n \times (\log n + \log M)),空间复杂度 O(logn)O(\log n)。其中 nn 是数组 priceprice 的长度;而 MM 是数组 priceprice 中的最大值,本题中 M109M \leq 10^9

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution:
    def maximumTastiness(self, price: List[int], k: int) -> int:
        def check(x: int) -> bool:
            cnt, pre = 0, -x
            for cur in price:
                if cur - pre >= x:
                    pre = cur
                    cnt += 1
            return cnt >= k

        price.sort()
        l, r = 0, price[-1] - price[0]
        while l < r:
            mid = (l + r + 1) >> 1
            if check(mid):
                l = mid
            else:
                r = mid - 1
        return l
speed

复杂度分析

指标
时间Depends on the final approach
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    Look for the candidate's understanding of binary search over a range of possible answers.

  • question_mark

    Check if the candidate effectively uses sorting and greedy methods to confirm the validity of a candidate solution.

  • question_mark

    Ensure the candidate can optimize the approach for both time and space, given the problem constraints.

warning

常见陷阱

外企场景
  • error

    Failing to sort the array before applying the greedy approach can result in incorrect selections of candies.

  • error

    Not properly adjusting the binary search bounds based on the feasibility of the current mid value.

  • error

    Overcomplicating the problem by using brute-force methods instead of the efficient binary search and greedy solution.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    What if the price array contains duplicate values? The approach remains the same, but you need to be mindful that some baskets may have a tastiness of 0.

  • arrow_right_alt

    What if k is always equal to the array length? The problem reduces to finding the smallest possible price difference between the candies.

  • arrow_right_alt

    How would the problem change if you were allowed to select fewer than k candies? This would require adjusting the feasibility check in the greedy approach.

help

常见问题

外企场景

礼盒的最大甜蜜度题解:二分·搜索·答案·空间 | LeetCode #2517 中等