File tree 1 file changed +54
-0
lines changed
docs/algorithm/research/binary-search
1 file changed +54
-0
lines changed Original file line number Diff line number Diff line change @@ -1240,4 +1240,58 @@ class Solution:
1240
1240
right = mid - 1
1241
1241
1242
1242
return - 1
1243
+ ```
1244
+
1245
+ ## 1283. 使结果不超过阈值的最小除数
1246
+
1247
+ [ 原题链接] ( https://leetcode-cn.com/problems/find-the-smallest-divisor-given-a-threshold/ )
1248
+
1249
+ ### 读题
1250
+
1251
+ 简单得说,就是找到一个正整数 ` x ` ,把 ` nums ` 中的数依次除以该数,相加之和 ` total ` 需要小于阈值 ` threshold ` ,且要求 ` x ` 最小。可知当 ` total ` 越接近 ` threshold ` 时,` x ` 越小。
1252
+
1253
+ ### 思路
1254
+
1255
+ 因为数据量的原因(1 <= nums.length <= 5 * 10^4),我们不能通过暴力破解枚举所有可能的 ` x ` ,可以想到应当使用二分查找,那么二分查找的区间如何定义呢?
1256
+
1257
+ 左侧值 ` left ` 选取最小正整数 1,而右侧值 ` right ` 可以选择数组 ` nums ` 中的最大数 ` max(nums) ` 。当 ` x ` 取值为 ` max(nums) ` 时,结果和 ` total ` 等于数组长度,若此时 ` x ` 再继续增加,` total ` 则始终保持不变。因此右侧区间取值 ` max(nums) ` ,再取更大的值则没有意义。
1258
+
1259
+ ### 实现
1260
+
1261
+ ``` go
1262
+ func smallestDivisor (nums []int , threshold int ) int {
1263
+ // 寻找最大数
1264
+ maxNum := 1
1265
+ for _ , num := range nums {
1266
+ if num > maxNum {
1267
+ maxNum = num
1268
+ }
1269
+ }
1270
+
1271
+ left := 1
1272
+ right := maxNum
1273
+ ans := 0
1274
+ for left <= right {
1275
+ mid := (left + right) / 2
1276
+ // 计算总数
1277
+ total := 0
1278
+ for _ , num := range nums {
1279
+ total += num / mid
1280
+ if num % mid > 0 {
1281
+ total += 1
1282
+ }
1283
+ }
1284
+
1285
+ if total <= threshold {
1286
+ // 找到满足条件的 mid 了,但还希望能找到更小的:往左边找
1287
+ right = mid - 1
1288
+ ans = mid
1289
+ } else {
1290
+ // total 太大了,应该要提高 mid:往右边找
1291
+ left = mid + 1
1292
+ }
1293
+ }
1294
+
1295
+ return ans
1296
+ }
1243
1297
```
You can’t perform that action at this time.
0 commit comments