leetcode 1283. Find the Smallest Divisor Given a Threshold

Given an array of integers nums and an integer threshold, we will choose a positive integer divisor and divide all the array by it and sum the result of the division. Find the smallest divisor such that the result mentioned above is less than or equal to threshold.

Each result of division is rounded to the nearest integer greater than or equal to that element. (For example: 7/3 = 3 and 10/2 = 5).

It is guaranteed that there will be an answer.

 

Example 1:

Input: nums = [1,2,5,9], threshold = 6
Output: 5
Explanation: We can get a sum to 17 (1+2+5+9) if the divisor is 1. 
If the divisor is 4 we can get a sum to 7 (1+1+2+3) and if the divisor is 5 the sum will be 5 (1+1+1+2). 

Example 2:

Input: nums = [2,3,5,7,11], threshold = 11
Output: 3

Example 3:

Input: nums = [19], threshold = 5
Output: 4

 

Constraints:

  • 1 <= nums.length <= 5 * 10^4
  • 1 <= nums[i] <= 10^6
  • nums.length <= threshold <= 10^6

題目難度:簡單題

題目思路:就是暴力窮舉,暴力窮舉過程中,因子逐漸自增。實際上,我們可以通過分析得到因子的上確界(大於這個值的所有因子,都將使得nums中的每一個值經過除法之後都爲1),這樣我們可以通過二分法,更快找到目標因子。

C++代碼:

 1 class Solution {
 2 private:
 3     int sum(vector<int>& nums, int divisor) {
 4         int sum = 0;
 5         for (auto n : nums) {
 6             sum += n / divisor + (n % divisor == 0 ? 0 : 1);
 7         }
 8         return sum;
 9     }
10 public:
11     int smallestDivisor(vector<int>& nums, int threshold) {
12         int left = 1;
13         int right = nums[nums.size() - 1]; //max nums
14         while (left <= right) {
15             int mid = left + ((right - left) >> 1);
16             int n = sum(nums, mid);
17             if (n > threshold) {
18                 left = mid + 1;
19             } else {
20                 right = mid - 1;
21             }
22         }
23         return left;
24     }
25 };

注:時間複雜度$O(nlogn)$,這裏假設了原數組有序,最後一個數爲最大值,否則需要先找到最大值($O(n)$的時間複雜度)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章