[Leetcode] 644. Maximum Average Subarray II 解题报告
2018-01-24 11:37
351 查看
题目:
Given an array consisting of
is greater than or equal to
to output the maximum average value.
Example 1:
Note:
1 <=
10,000.
Elements of the given array will be in range [-10,000, 10,000].
The answer with the calculation error less than 10-5 will be accepted.
思路:
确实是一道很难的题目,我开始的时候一直想用DP解决,奈何死活找不出递推公式。后来参考了网上的二分查找思路,感觉还是挺巧妙的:
我们首先找出数组中的最小值left和最大值right,因为这将构成最大平均值的区间。然后每次找到left和right的平均值mid,对于mid,在数组内找是否存在一个长度大于等于k的连续区间,其平均值大于mid,如果存在,那么说明mid还不是最大平均值,所以修改左边界left;否则说明mid已经大于等于左右长度大于等于k的所有连续区间的最大平均值了,所以此时修改右边界right。这样当left和right逐渐收敛到一点的时候,该收敛点就是最大平均值。
该算法的空间复杂度是O(1),时间复杂度是O(logm*n),其中n是nums的长度,而m则是nums中最大值和最小值的差。虽然m有可能很大,但是被log了,所以该时间复杂度接近于O(n),还是非常不错的。
代码:class Solution {
public:
double findMaxAverage(vector<int>& nums, int k) {
double left = INT_MAX, right = INT_MIN, mid;
for (int num : nums) {
right = max(right, double(num)); // the max value in the array
left = min(left, double(num)); // the min value in the array
}
while (left + 0.00001 < right) { //threshold
mid = left + (right - left) / 2;
if(islarger(nums, mid, k)) {
right = mid;
}
else {
left = mid;
}
}
return left;
}
private:
// Return true when mid is larger than or equal to the maximum average value;
// Return false when mid is smaller than the maximum average value.
bool islarger(vector<int>& nums, double mid, int k){
// sum: the sum from nums[0] to nums[i];
// prev_sum: the sum from nums[0] to nums[i-k];
// min_sum: the minimal sum from nums[0] to nums[j] ( 0=< j <= i-k );
double sum = 0, prev_sum = 0, min_sum = 0;
for(int i = 0; i < nums.size(); i++){
sum += nums[i] - mid;
if (i >= k) {
prev_sum += nums[i-k] - mid;
min_sum = min(prev_sum, min_sum);
}
if(i >= k-1 && sum > min_sum) { // there exists an range in which the average value is larger
return false;
}
}
return true;
}
};
Given an array consisting of
nintegers, find the contiguous subarray whose length
is greater than or equal to
kthat has the maximum average value. And you need
to output the maximum average value.
Example 1:
Input: [1,12,-5,-6,50,3], k = 4 Output: 12.75 Explanation: when length is 5, maximum average value is 10.8, when length is 6, maximum average value is 9.16667. Thus return 12.75.
Note:
1 <=
k<=
n<=
10,000.
Elements of the given array will be in range [-10,000, 10,000].
The answer with the calculation error less than 10-5 will be accepted.
思路:
确实是一道很难的题目,我开始的时候一直想用DP解决,奈何死活找不出递推公式。后来参考了网上的二分查找思路,感觉还是挺巧妙的:
我们首先找出数组中的最小值left和最大值right,因为这将构成最大平均值的区间。然后每次找到left和right的平均值mid,对于mid,在数组内找是否存在一个长度大于等于k的连续区间,其平均值大于mid,如果存在,那么说明mid还不是最大平均值,所以修改左边界left;否则说明mid已经大于等于左右长度大于等于k的所有连续区间的最大平均值了,所以此时修改右边界right。这样当left和right逐渐收敛到一点的时候,该收敛点就是最大平均值。
该算法的空间复杂度是O(1),时间复杂度是O(logm*n),其中n是nums的长度,而m则是nums中最大值和最小值的差。虽然m有可能很大,但是被log了,所以该时间复杂度接近于O(n),还是非常不错的。
代码:class Solution {
public:
double findMaxAverage(vector<int>& nums, int k) {
double left = INT_MAX, right = INT_MIN, mid;
for (int num : nums) {
right = max(right, double(num)); // the max value in the array
left = min(left, double(num)); // the min value in the array
}
while (left + 0.00001 < right) { //threshold
mid = left + (right - left) / 2;
if(islarger(nums, mid, k)) {
right = mid;
}
else {
left = mid;
}
}
return left;
}
private:
// Return true when mid is larger than or equal to the maximum average value;
// Return false when mid is smaller than the maximum average value.
bool islarger(vector<int>& nums, double mid, int k){
// sum: the sum from nums[0] to nums[i];
// prev_sum: the sum from nums[0] to nums[i-k];
// min_sum: the minimal sum from nums[0] to nums[j] ( 0=< j <= i-k );
double sum = 0, prev_sum = 0, min_sum = 0;
for(int i = 0; i < nums.size(); i++){
sum += nums[i] - mid;
if (i >= k) {
prev_sum += nums[i-k] - mid;
min_sum = min(prev_sum, min_sum);
}
if(i >= k-1 && sum > min_sum) { // there exists an range in which the average value is larger
return false;
}
}
return true;
}
};
相关文章推荐
- Leetcode 644. Maximum Average Subarray II 最大平均区间2 解题报告
- LeetCode解题报告 --- Single Number II
- LeetCode解题报告:Linked List Cycle && Linked List Cycle II
- [leetcode] 213. House Robber II 解题报告
- LeetCode 644: Maximum Average Subarray II
- [LeetCode] Unique Paths II 解题报告
- Leetcode 113. Path Sum II 路径和2 解题报告
- Leetcode 92. Reverse Linked List II 翻转链表2 解题报告
- 【LeetCode】Palindrome Partitioning II 解题报告
- 【LeetCode】560.Subarray Sum Equals K解题报告
- 【LeetCode】53.Maximum Subarray解题报告
- [Leetcode] 213. House Robber II 解题报告
- LeetCode解题报告--Combination Sum II
- [Leetcode] 272. Closest Binary Search Tree Value II 解题报告
- [LeetCode] Pascal's Triangle II 解题报告
- [LeetCode] Remove Duplicates from Sorted Array II 解题报告
- [LeetCode]Binary Tree Level Order Traversal II,解题报告
- [Leetcode] 718. Maximum Length of Repeated Subarray 解题报告
- LeetCode: Populating Next Right Pointers in Each Node II 解题报告
- 【LeetCode】Path Sum II 解题报告