Smallest Subarray with Sum K from an Array
Given an array arr[] consisting of N integers, the task is to find the length of the Smallest subarray with a sum equal to K.
Examples:
Input: arr[] = {2, 4, 6, 10, 2, 1}, K = 12
Output: 2
Explanation: All possible subarrays with sum 12 are {2, 4, 6} and {10, 2}.
Input: arr[] = {-8, -8, -3, 8}, K = 5
Output: 2
Naive Approach: The simplest approach to solve the problem is to generate all possible subarrays and for each subarray, check if its sum is equal to K or not. Print the minimum length of all such subarrays.
C++
#include <bits/stdc++.h>
using namespace std;
int smallestSubarraySumK(vector< int >& arr, int k)
{
int result = INT_MAX;
for ( int i = 0; i < arr.size(); ++i) {
int sum = 0;
for ( int j = i; j < arr.size(); j++) {
sum += arr[j];
if (sum == k) {
result = min(result, (j - i + 1));
}
}
}
return result;
}
int main()
{
vector< int > arr = { -8, -8, -3, 8 };
int k = 5;
int result = smallestSubarraySumK(arr, k);
if (result == INT_MAX)
cout << -1;
else
cout << result;
return 0;
}
|
Java
import java.util.*;
class GFG {
static int smallestSubarraySumK( int [] arr, int k)
{
int result = Integer.MAX_VALUE;
for ( int i = 0 ; i < arr.length; ++i) {
int sum = 0 ;
for ( int j = i; j < arr.length; j++) {
sum += arr[j];
if (sum == k) {
result = Math.min(result, (j - i + 1 ));
}
}
}
return result;
}
public static void main (String[] args) {
int [] arr = { - 8 , - 8 , - 3 , 8 };
int k = 5 ;
int result = smallestSubarraySumK(arr, k);
if (result == Integer.MAX_VALUE)
System.out.println(- 1 );
else
System.out.println(result);
}
}
|
Python3
import math
def smallestSubarraySumK(arr, k):
result = 2147483647 ;
for i in range ( 0 , len (arr)):
ans = 0 ;
for j in range (i, len (arr)):
ans + = arr[j];
if (ans = = k):
result = min (result, (j - i + 1 ));
return result;
arr = [ - 8 , - 8 , - 3 , 8 ];
k = 5 ;
result = smallestSubarraySumK(arr, k);
if (result = = 2147483647 ):
print ( - 1 );
else :
print (result);
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int smallestSubarraySumK(List< int > arr, int k)
{
int result = Int32.MaxValue;
for ( int i = 0; i < arr.Count; ++i) {
int sum = 0;
for ( int j = i; j < arr.Count; j++) {
sum += arr[j];
if (sum == k) {
result = Math.Min(result, (j - i + 1));
}
}
}
return result;
}
public static void Main()
{
List< int > arr = new List< int >{ -8, -8, -3, 8 };
int k = 5;
int result = smallestSubarraySumK(arr, k);
if (result == Int32.MaxValue)
Console.Write(-1);
else
Console.Write(result);
}
}
|
Javascript
function smallestSubarraySumK(arr, k)
{
let result = Number.MAX_SAFE_INTEGER;
for (let i = 0; i < arr.length; ++i) {
let sum = 0;
for (let j = i; j < arr.length; j++) {
sum += arr[j];
if (sum == k) {
result = Math.min(result, (j - i + 1));
}
}
}
return result;
}
let arr = [ -8, -8, -3, 8 ];
let k = 5;
let result = smallestSubarraySumK(arr, k);
if (result == Number.MAX_SAFE_INTEGER)
document.write(-1);
else
document.write(result);
|
Time Complexity: O(N2)
Auxiliary Space: O(1)
Efficient approach: The above approach can be further optimized using the Prefix Sum technique and Map.
Follow the steps below to solve the problem:
- currPrefixSum will store the prefix sum ending at ith index.
- Iterate over the array and keep calculating currPrefixSum.
- Check if, currPrefixSum is equal to K.
- If yes, then use this length of subarray (currPrefixSum) to minimize the result.
- Also, check if the required prefix sum (currPrefixSum – K) has been calculated previously or not.
- If the required prefix sum is calculated previously then find its last occurrence of that prefix sum and use it to calculate the length of the current prefix sum equal to K by (current index – last occurrence of required prefix sum) and use it to minimize the result.
- Store the currPrefixSum which is ending at ith index into the map.
- Finally, return the result.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int smallestSubarraySumK(vector< int > & arr, int k ){
unordered_map< long long , int > unmap;
int n = arr.size();
long long currPrefixSum = 0;
long long result = INT_MAX;
for ( int i = 0; i < n; i++){
currPrefixSum += arr[i];
if (currPrefixSum == k){
long long currLen = i + 1;
result = min(result, currLen);
}
long long requirePrefixSum
= currPrefixSum - k;
if (unmap.count(requirePrefixSum)){
long long foundIdx =
unmap[requirePrefixSum];
long long currIdx = i;
result = min(result,
currIdx - foundIdx);
}
unmap[currPrefixSum] = i;
}
if (result >= INT_MAX) return -1;
return result;
}
int main(){
vector< int > arr = {-8, -8, -3, 8};
int k = 5;
cout << smallestSubarraySumK(arr, k);
return 0;
}
|
Java
import java.util.*;
public class Main {
static int smallestSubarraySumK( int arr[], int n, int K)
{
HashMap<Integer,
Integer> mp = new HashMap<Integer,
Integer>();
int currPrefixSum = 0 ;
int result = Integer.MAX_VALUE;
for ( int i = 0 ; i < n; i++){
currPrefixSum += arr[i];
if (currPrefixSum == K){
int currLen = i + 1 ;
result = Math.min(result, currLen);
}
int requirePrefixSum = currPrefixSum - K;
if (mp.containsKey(requirePrefixSum)){
int foundIdx = mp.get(requirePrefixSum);
int currIdx = i;
result = Math.min(result, currIdx
- foundIdx);
}
mp.put(currPrefixSum, i);
}
if (result >= Integer.MAX_VALUE) return - 1 ;
return result;
}
public static void main(String[] args){
int arr[] = {- 8 , - 8 , - 3 , 8 };
int n = arr.length;
int K = 5 ;
System.out.println(smallestSubarraySumK(arr,
n, K));
}
}
|
Python3
from collections import defaultdict
import sys
def subArraylen(arr, n, K):
mp = defaultdict( lambda : 0 )
currPrefixSum = 0
result = sys.maxsize
for i in range (n):
currPrefixSum + = arr[i]
if (currPrefixSum = = K):
currLen = i + 1
result = min (result, currLen)
requirePrefixSum = currPrefixSum - K
if (requirePrefixSum in mp.keys()):
foundIdx = mp[requirePrefixSum]
currIdx = i
result = min (result, currIdx - foundIdx)
mp[currPrefixSum] = i
return result
if __name__ = = "__main__" :
arr = [ - 8 , - 8 , - 3 , 8 ]
n = len (arr)
K = 5
ln = subArraylen(arr, n, K)
if (ln = = sys.maxsize):
print ( "-1" )
else :
print (ln)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int smallestSubarraySumK( int [] arr, int n, int K)
{
Dictionary< int , int > mp = new Dictionary< int , int >();
int currPrefixSum = 0;
int result = int .MaxValue;
for ( int i = 0; i < n; i++)
{
currPrefixSum += arr[i];
if (currPrefixSum == K)
{
int currLen = i + 1;
result = Math.Min(result, currLen);
}
int requirePrefixSum = currPrefixSum - K;
if (mp.ContainsKey(requirePrefixSum))
{
int foundIdx = mp[requirePrefixSum];
int currIdx = i;
result = Math.Min(result, currIdx
- foundIdx);
}
mp[currPrefixSum] = i;
}
if (result >= int .MaxValue) return -1;
return result;
}
public static void Main()
{
int [] arr = { -8, -8, -3, 8 };
int n = arr.Length;
int K = 5;
Console.Write(smallestSubarraySumK(arr,
n, K));
}
}
|
Javascript
<script>
function smallestSubarraySumK(arr,k)
{
let unmap = new Map();
let n = arr.length
let currPrefixSum = 0;
let result = Number.MAX_VALUE;
for (let i = 0; i < n; i++)
{
currPrefixSum += arr[i];
if (currPrefixSum == k){
let currLen = i + 1;
result = Math.min(result, currLen);
}
let requirePrefixSum
= currPrefixSum - k;
if (unmap.has(requirePrefixSum)){
let foundIdx =
unmap.get(requirePrefixSum);
let currIdx = i;
result = Math.min(result,
currIdx - foundIdx);
}
unmap.set(currPrefixSum, i);
}
if (result >= Number.MAX_VALUE) return -1;
return result;
}
let arr = [-8, -8, -3, 8];
let k = 5;
document.write(smallestSubarraySumK(arr, k));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Last Updated :
20 Jan, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...