[LeetCode] 2517. Maximum Tastiness of Candy Basket

You are given an array of positive integers price where price[i] denotes the price of the ith candy and a positive integer k.

The store sells baskets of k distinct candies. The tastiness of a candy basket is the smallest absolute difference of the prices of any two candies in the basket.

Return the maximum tastiness of a candy basket.

Example 1:

Input: price = [13,5,1,8,21,2], k = 3
Output: 8
Explanation: Choose the candies with the prices [13,5,21].
The tastiness of the candy basket is: min(|13 - 5|, |13 - 21|, |5 - 21|) = min(8, 8, 16) = 8.
It can be proven that 8 is the maximum tastiness that can be achieved.

Example 2:

Input: price = [1,3,1], k = 2
Output: 2
Explanation: Choose the candies with the prices [1,3].
The tastiness of the candy basket is: min(|1 - 3|) = min(2) = 2.
It can be proven that 2 is the maximum tastiness that can be achieved.

Example 3:

Input: price = [7,7,7,7], k = 2
Output: 0
Explanation: Choosing any two distinct candies from the candies we have will result in a tastiness of 0. 

Constraints:

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

礼盒的最大甜蜜度。

给你一个正整数数组 price ,其中 price[i] 表示第 i 类糖果的价格,另给你一个正整数 k 。
商店组合 k 类 不同 糖果打包成礼盒出售。礼盒的 甜蜜度 是礼盒中任意两种糖果 价格 绝对差的最小值。
返回礼盒的 最大 甜蜜度。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/maximum-tastiness-of-candy-basket
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路是排序 + 二分,而且这道题是在答案上做二分。

首先我们思考一下暴力解。为了得到一个合适的甜蜜度,同时尽快地找到每两个礼盒之间价格的差值,我们势必要对 input 数组排序,这样我们才能尽快找到甜蜜度相邻的礼盒之间的差值。排序之后,因为需要找 k 个礼盒,那么我们需要一个两层循环,第一层遍历每 k 个礼盒的第一个,第二层我们需要去看 k 个礼盒,并计算他们两两间价格绝对差的最小值。如果 k 非常大,暴力解的时间复杂度会到 O(nk),几乎就是一个两层 for 循环的速度。

优化的办法是排序 + 二分。这里排序还是必不可少,因为需要以最快的速度找到礼盒间的价格差。这里我们对答案进行二分,意思是我们去猜测一个绝对差,看看这个差值是否能让我们找到 k 个礼盒。为了简单起见,二分的下界我取 0,上界我取 Integer.MAX_VALUE。这道题二分的代码稍微有一些特殊,我写的时候选择了左闭右开的方式(left < right)。当我们找到一个 mid 值的时候,我们去尝试看看 helper 函数是否能返回 true,如果返回,说明这个猜测的 mid 值一定能满足题意,left = mid + 1。当我们跳出 while 循环的时候,因为在跳出前 left = mid + 1,mid 是跳出之前能找到的最小的合法值,所以最后返回的是 left - 1,其实就是 mid。

时间O(n^2)

空间O(1)

Java实现

 1 class Solution {
 2     public int maximumTastiness(int[] price, int k) {
 3         Arrays.sort(price);
 4         int n = price.length;
 5         int left = 0;
 6         int right = Integer.MAX_VALUE;
 7         while (left < right) {
 8             int mid = left + (right - left) / 2;
 9             if (helper(mid, price, k)) {
10                 left = mid + 1;
11             } else {
12                 right = mid;
13             }
14         }
15         return left - 1;
16     }
17 
18     private boolean helper(int target, int[] price, int k) {
19         int prev = price[0];
20         int count = 1;
21         for (int i = 1; i < price.length; i++) {
22             if (price[i] - prev >= target) {
23                 count++;
24                 prev = price[i];
25             }
26             if (count == k) {
27                 return true;
28             }
29         }
30         return false;
31     }
32 }

 

LeetCode 题目总结

posted @ 2023-01-03 11:12  CNoodle  阅读(302)  评论(0编辑  收藏  举报