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)$的時間複雜度)