Find the subarray with least average

来源:互联网 发布:unix编程艺术 pdf 编辑:程序博客网 时间:2024/06/07 10:12

转自:http://www.geeksforgeeks.org/find-subarray-least-average/

Given an array arr[] of size n and integer k such that k <= n.

Input:  arr[] = {3, 7, 90, 20, 10, 50, 40}, k = 3Output: Subarray between indexes 3 and 5The subarray {20, 10, 50} has the least average among all subarrays of size 3.Input:  arr[] = {3, 7, 5, 20, -10, 0, 12}, k = 2Output: Subarray between [4, 5] has minimum average

We strongly recommend you to minimize your browser and try this yourself first.

A Simple Solution is to consider every element as beginning of subarray of size k and compute sum of subarray starting with this element. Time complexity of this solution is O(nk).

An Efficient Solution is to solve the above problem in O(n) time and O(1) extra space. The idea is to use sliding window of size k. Keep track of sum of current k elements. To compute sum of current window, remove first element of previous window and add current element (last element of current window).

1) Initialize res_index = 0 // Beginning of result index2) Find sum of first k elements. Let this sum be 'curr_sum'3) Initialize min_sum = sum4) Iterate from (k+1)'th to n'th element, do following   for every element arr[i]      a) curr_sum = curr_sum + arr[i] - arr[i-k]      b) If curr_sum < min_sum           res_index = (i-k+1)5) Print res_index and res_index+k-1 as beginning and ending   indexes of resultant subarray.

Below is C++ implementation of above algorithm.

// A Simple C++ program to find minimum average subarray
#include<bits/stdc++.h>
usingnamespace std;
 
// Prints beginning and ending indexes of subarray
// of size k with minimum average
voidfindMinAvgSubarray(intarr[], int n, int k)
{
    // k must be smaller than or equal to n
    if(n < k)
       return;
 
    // Initialize  beginning index of result
    intres_index = 0;
 
    // Compute sum of first subarray of size k
    intcurr_sum = 0;
    for(int i=0; i<k; i++)
       curr_sum += arr[i];
 
    // Initialize minimum sum as current sum
    intmin_sum = curr_sum;
 
    // Traverse from (k+1)'th element to n'th element
    for(int i = k; i < n; i++)
    {
        // Add current item and remove first item of
        // previous subarray
        curr_sum += arr[i] - arr[i-k];
 
        // Update result if needed
        if(curr_sum < min_sum)
        {
            min_sum = curr_sum;
            res_index = (i-k+1);
        }
    }
 
    cout <<"Subarray between [" << res_index << ", "
        << res_index + k - 1<<"] has minimum average";
}
 
// Driver program
int main()
{
    intarr[] = {3, 7, 90, 20, 10, 50, 40};
    intk = 3; // Subarray size
    intn = sizeof arr / sizeof arr[0];
    findMinAvgSubarray(arr, n, k);
    return0;
}

0 0
原创粉丝点击