Smallest subarray from a given Array with sum greater than or equal to K

• Difficulty Level : Hard
• Last Updated : 28 Jul, 2020

Given an array A[] consisting of N integers and an integer K, the task is to find the length of the smallest subarray with sum greater than or equal to K. If no such subarray exists, print -1.

Examples:

Input: A[] = {2, -1, 2}, K = 3
Output: 3
Explanation:
Sum of the given array is 3.
Hence, the smallest possible subarray satisfying the required condition is the entire array.
Therefore, the length is 3.

Input: A[] = {2, 1, 1, -4, 3, 1, -1, 2}, K = 5
Output: 4

Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Naive Approach:
The simplest approach to solve the problem is to generate all possible subarrays of the given array and check which subarray sum is greater than or equal to K. Among all such subarrays satisfying the condition, print the subarray having minimum length.
Time Complexity:O(N2)
Auxiliary Space: O(1)

Efficient Approach:
The above approach can be further optimized using Prefix Sum Array and Binary search. Follow the steps below:

• Initialize an array to store the Prefix sum of the original array.
• Hash the prefix sum array with the indices using a Map.
• If a greater sum with a lesser index is already found, then there is no point of hashing a prefix sum which is smaller than the largest prefix sum obtained till now. Therefore, hash the increasing order of prefix sum.
• Traversing the array and if any element is greater than or equal to K, return 1 as the answer.
• Otherwise, for every element, perform Binary Search over the indices (i, n-1) in the prefix sum array to find the first index with sum at least K.
• Return the minimum length subarray obtained from the above steps.

Below is the implementation of the above approach:

C++

 // C++ Program to implement// the above approach#include using namespace std;  // Function to perform Binary Search// and return the smallest index with// sum greater than valueint binary_search(map >& m,                  int value, int index){    // Search the value in map    auto it = m.lower_bound(value);      // If all keys in the map    // are less then value    if (it == m.end())        return 0;      // Check if the sum is found    // at a greater index    auto it1        = lower_bound(it->second.begin(),                      it->second.end(), index);      if ((it1 - it->second.begin())        != it->second.size())        return *it1;      return 0;}  // Function to find the smallest subarray// with sum greater than equal to Kint findSubarray(int arr[], int n, int k){      // Prefix sum array    int pre_array[n];      // Stores the hashes to prefix sum    map > m;      pre_array = arr;    m[pre_array].push_back(0);      // If any array element is    // greater than equal to k    if (arr >= k)        return 1;      int ans = INT_MAX;    for (int i = 1; i < n; i++) {          pre_array[i]            = arr[i] + pre_array[i - 1];          // If prefix sum exceeds K        if (pre_array[i] >= k)              // Update size of subarray            ans = min(ans, i + 1);          auto it = m.rbegin();          // Hash prefix sum in        // increasing order        if (pre_array[i] >= it->first)            m[pre_array[i]].push_back(i);    }      for (int i = 1; i < n; i++) {          int temp            = binary_search(m,                            pre_array[i - 1] + k,                            i);        if (temp == 0)            continue;          // Update size of subarray        ans = min(ans, temp - i + 1);    }      // If any subarray is found    if (ans <= n)        return ans;      // If no such subarray exists    return -1;}  // Driver Codeint main(){    int arr[] = { 2, 1, 1, -4, 3, 1, -1, 2 };      int k = 5;      int n = sizeof(arr) / sizeof(arr);      cout << findSubarray(arr, n, k) << endl;      return 0;}
Output:
4

Time Complexity: O(NlogN)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up