5656
5757<!-- 这里可写通用的实现逻辑 -->
5858
59- ** 方法一:二分查找**
59+ ** 方法一:贪心 + 二分查找**
6060
61- 我们先对数组 ` price ` 进行排序,然后二分枚举甜蜜度,找到最大的且满足至少有 $k$ 类糖果的甜蜜度 。
61+ 我们注意到,如果一个甜蜜度为 $x$ 的礼盒是可行的,那么所有甜蜜度小于 $x$ 的礼盒也是可行的,这存在单调性,因此可以使用二分查找的方法找到最大的可行甜蜜度 。
6262
63- 时间复杂度 $O(n \times \log M),ドル空间复杂度 $O(1)$。其中 $n$ 为数组 ` price ` 的长度,而 $M$ 为数组 ` price ` 中的最大值。本题中我们取 $M = 10^9$。
63+ 我们首先将数组 $price$ 排序,然后定义二分查找的左边界 $l=0,ドル $r=price[ n-1] -price[ 0] $。每一次,我们计算出当前的中间值 $mid = \lfloor \frac{l+r+1}{2} \rfloor,ドル以 $mid$ 作为甜蜜度,判断是否可行。若可行,那么我们将左边界 $l$ 更新为 $mid,ドル否则将右边界 $r$ 更新为 $mid-1$。最后返回 $l$ 即可。
64+ 65+ 那么问题的关键就是判断一个甜蜜度是否可行,我们通过函数 $check(x)$ 来判断。函数 $check(x)$ 的实现逻辑如下:
66+ 67+ 定义一个变量 $cnt$ 表示当前已经选取的糖果的数量,初始值为 0ドル,ドル定义一个变量 $pre$ 表示上一个选取的糖果的价格,初始值为 $-x$。然后我们遍历排好序的数组 $price,ドル对于每一个糖果的价格 $cur,ドル如果 $cur-pre \geq x,ドル那么我们就选取这个糖果,将 $pre$ 更新为 $cur,ドル并将 $cnt$ 加一。最后判断 $cnt$ 是否大于等于 $k,ドル如果是,那么返回 $true,ドル否则返回 $false$。
68+ 69+ 时间复杂度 $O(n \times (\log n + \log M)),ドル空间复杂度 $O(\log n)$。其中 $n$ 是数组 $price$ 的长度;而 $M$ 是数组 $price$ 中的最大值,本题中 $M \leq 10^9$。
6470
6571<!-- tabs:start -->
6672
7177``` python
7278class Solution :
7379 def maximumTastiness (self , price : List[int ], k : int ) -> int :
74- def check (x ):
75- cnt = 1
76- s = price[0 ]
77- for p in price[1 :]:
78- if p - s >= x:
79- s = p
80+ def check (x : int ) -> bool :
81+ cnt, pre = 0 , - x
82+ for cur in price:
83+ if cur - pre >= x:
84+ pre = cur
8085 cnt += 1
8186 return cnt >= k
8287
8388 price.sort()
84- left, right = 0 , 10 ** 9
85- while left < right :
86- mid = (left + right + 1 ) >> 1
89+ l, r = 0 , price[ - 1 ] - price[ 0 ]
90+ while l < r :
91+ mid = (l + r + 1 ) >> 1
8792 if check(mid):
88- left = mid
93+ l = mid
8994 else :
90- right = mid - 1
91- return left
95+ r = mid - 1
96+ return l
9297```
9398
9499### ** Java**
@@ -97,31 +102,25 @@ class Solution:
97102
98103``` java
99104class Solution {
100- private int [] price;
101- private int k;
102- 103105 public int maximumTastiness (int [] price , int k ) {
104106 Arrays . sort(price);
105- this . price = price;
106- this . k = k;
107- int left = 0 , right = 1000000000 ;
108- while (left < right) {
109- int mid = (left + right + 1 ) >> 1 ;
110- if (check(mid)) {
111- left = mid;
107+ int l = 0 , r = price[price. length - 1 ] - price[0 ];
108+ while (l < r) {
109+ int mid = (l + r + 1 ) >> 1 ;
110+ if (check(price, k, mid)) {
111+ l = mid;
112112 } else {
113- right = mid - 1 ;
113+ r = mid - 1 ;
114114 }
115115 }
116- return left ;
116+ return l ;
117117 }
118118
119- private boolean check (int x ) {
120- int s = price[0 ];
121- int cnt = 1 ;
122- for (int i = 1 ; i < price. length; ++ i) {
123- if (price[i] - s >= x) {
124- s = price[i];
119+ private boolean check (int [] price , int k , int x ) {
120+ int cnt = 0 , pre = - x;
121+ for (int cur : price) {
122+ if (cur - pre >= x) {
123+ pre = cur;
125124 ++ cnt;
126125 }
127126 }
@@ -137,27 +136,26 @@ class Solution {
137136public:
138137 int maximumTastiness(vector<int >& price, int k) {
139138 sort(price.begin(), price.end());
140- int left = 0, right = 1e9;
141- auto check = [ &] (int x) {
142- int s = price[ 0] ;
143- int cnt = 1;
144- for (int i = 1; i < price.size(); ++i) {
145- if (price[ i] - s >= x) {
146- s = price[ i] ;
139+ int l = 0, r = price.back() - price[ 0] ;
140+ auto check = [ &] (int x) -> bool {
141+ int cnt = 0, pre = -x;
142+ for (int& cur : price) {
143+ if (cur - pre >= x) {
144+ pre = cur;
147145 ++cnt;
148146 }
149147 }
150148 return cnt >= k;
151149 };
152- while (left < right ) {
153- int mid = (left + right + 1) >> 1;
150+ while (l < r ) {
151+ int mid = (l + r + 1) >> 1;
154152 if (check(mid)) {
155- left = mid;
153+ l = mid;
156154 } else {
157- right = mid - 1;
155+ r = mid - 1;
158156 }
159157 }
160- return left ;
158+ return l ;
161159 }
162160};
163161```
@@ -167,27 +165,76 @@ public:
167165```go
168166func maximumTastiness(price []int, k int) int {
169167 sort.Ints(price)
170- check := func(x int) bool {
171- s := price[0]
172- cnt := 1
173- for _, p := range price[1:] {
174- if p-s >= x {
175- s = p
168+ return sort.Search(price[len(price)-1], func(x int) bool {
169+ cnt, pre := 0, -x
170+ for _, cur := range price {
171+ if cur-pre >= x {
172+ pre = cur
176173 cnt++
177174 }
178175 }
179- return cnt >= k
180- }
181- left, right := 0, 1000000000
182- for left < right {
183- mid := (left + right + 1) >> 1
184- if check(mid) {
185- left = mid
186- } else {
187- right = mid - 1
188- }
189- }
190- return left
176+ return cnt < k
177+ }) - 1
178+ }
179+ ```
180+ 181+ ### ** TypeScript**
182+ 183+ ``` ts
184+ function maximumTastiness(price : number [], k : number ): number {
185+ price .sort ((a , b ) => a - b );
186+ let l = 0 ;
187+ let r = price [price .length - 1 ] - price [0 ];
188+ const check = (x : number ): boolean => {
189+ let [cnt, pre] = [0 , - x ];
190+ for (const cur of price ) {
191+ if (cur - pre >= x ) {
192+ pre = cur ;
193+ ++ cnt ;
194+ }
195+ }
196+ return cnt >= k ;
197+ };
198+ while (l < r ) {
199+ const mid = (l + r + 1 ) >> 1 ;
200+ if (check (mid )) {
201+ l = mid ;
202+ } else {
203+ r = mid - 1 ;
204+ }
205+ }
206+ return l ;
207+ }
208+ ```
209+ 210+ ### ** C#**
211+ 212+ ``` cs
213+ public class Solution {
214+ public int MaximumTastiness (int [] price , int k ) {
215+ Array .Sort (price );
216+ int l = 0 , r = price [price .Length - 1 ] - price [0 ];
217+ while (l < r ) {
218+ int mid = (l + r + 1 ) >> 1 ;
219+ if (check (price , mid , k )) {
220+ l = mid ;
221+ } else {
222+ r = mid - 1 ;
223+ }
224+ }
225+ return l ;
226+ }
227+ 228+ private bool check (int [] price , int x , int k ) {
229+ int cnt = 0 , pre = - x ;
230+ foreach (int cur in price ) {
231+ if (cur - pre >= x ) {
232+ ++ cnt ;
233+ pre = cur ;
234+ }
235+ }
236+ return cnt >= k ;
237+ }
191238}
192239```
193240
0 commit comments