Given an array arr[] of size N containing integers. The task is to find the length of the longest sub-array having sum equal to the given value K.
Examples:
Input: arr[] = {2, 3, 4, 2, 1, 1}, K = 10
Output: 4
Explanation:
The subarray {3, 4, 2, 1} gives summation as 10.Input: arr[] = {6, 8, 14, 9, 4, 11, 10}, K = 13
Output: 2
Explanation:
The subarray {9, 4} gives summation as 13.
Naive Approach: Please refer to this article.
Time Complexity: O(N2)
Auxiliary Space: O(1)
Efficient Approach: The idea is to use Binary Search to find the subarray of maximum length having sum K. Below are the steps:
- Create a prefix sum array(say pref[]) from the given array arr[].
-
For each element in the prefix array pref[] do Binary Search:
- Initialize ans, start and end variables as -1, 0, and N respectively.
- Find the middle index(say mid).
- If pref[mid] – val ? K then update the start variable to mid + 1 and ans to mid.
- Else update the end variable to mid – 1.
- Return the value of ans from the above binary search.
- If current subarray length is less than (ans – i), then update the maximum length to (ans – i).
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// To store the prefix sum array vector< int > v;
// Function for searching the // lower bound of the subarray int bin( int val, int k, int n)
{ int lo = 0;
int hi = n;
int mid;
int ans = -1;
// Iterate until low less
// than equal to high
while (lo <= hi) {
mid = lo + (hi - lo) / 2;
// For each mid finding sum
// of sub array less than
// or equal to k
if (v[mid] - val <= k) {
lo = mid + 1;
ans = mid;
}
else
hi = mid - 1;
}
// Return the final answer
return ans;
} // Function to find the length of // subarray with sum K void findSubarraySumK( int arr[], int N, int K)
{ // Initialize sum to 0
int sum = 0;
v.push_back(0);
// Push the prefix sum of the
// array arr[] in prefix[]
for ( int i = 0; i < N; i++) {
sum += arr[i];
v.push_back(sum);
}
int l = 0, ans = 0, r;
for ( int i = 0; i < N; i++) {
// Search r for each i
r = bin(v[i], K, N);
// Update ans
ans = max(ans, r - i);
}
// Print the length of subarray
// found in the array
cout << ans;
} // Driver Code int main()
{ // Given array arr[]
int arr[] = { 6, 8, 14, 9, 4, 11, 10 };
int N = sizeof (arr) / sizeof (arr[0]);
// Given sum K
int K = 13;
// Function Call
findSubarraySumK(arr, N, K);
return 0;
} |
// Java program for the above approach import java.util.*;
class GFG {
// To store the prefix sum array
static Vector<Integer> v = new Vector<Integer>();
// Function for searching the
// lower bound of the subarray
static int bin( int val, int k, int n)
{
int lo = 0 ;
int hi = n;
int mid;
int ans = - 1 ;
// Iterate until low less
// than equal to high
while (lo <= hi) {
mid = lo + (hi - lo) / 2 ;
// For each mid finding sum
// of sub array less than
// or equal to k
if (v.get(mid) - val <= k) {
lo = mid + 1 ;
ans = mid;
}
else
hi = mid - 1 ;
}
// Return the final answer
return ans;
}
// Function to find the length of
// subarray with sum K
static void findSubarraySumK( int arr[], int N, int K)
{
// Initialize sum to 0
int sum = 0 ;
v.add( 0 );
// Push the prefix sum of the
// array arr[] in prefix[]
for ( int i = 0 ; i < N; i++) {
sum += arr[i];
v.add(sum);
}
int l = 0 , ans = 0 , r;
for ( int i = 0 ; i < v.size(); i++) {
// Search r for each i
r = bin(v.get(i), K, N);
// Update ans
ans = Math.max(ans, r - i);
}
// Print the length of subarray
// found in the array
System.out.print(ans);
}
// Driver Code
public static void main(String[] args)
{
// Given array arr[]
int arr[] = { 6 , 8 , 14 , 9 , 4 , 11 , 10 };
int N = arr.length;
// Given sum K
int K = 13 ;
// Function call
findSubarraySumK(arr, N, K);
}
} // This code is contributed by gauravrajput1 |
# Python3 program for the above approach # To store the prefix sum1 array v = []
# Function for searching the # lower bound of the subarray def bin1(val, k, n):
global v
lo = 0
hi = n
mid = 0
ans = - 1
# Iterate until low less
# than equal to high
while (lo < = hi):
mid = lo + ((hi - lo) / / 2 )
# For each mid finding sum1
# of sub array less than
# or equal to k
if (v[mid] - val < = k):
lo = mid + 1
ans = mid
else :
hi = mid - 1
# Return the final answer
return ans
# Function to find the length of # subarray with sum1 K def findSubarraysum1K(arr, N, K):
global v
# Initialize sum1 to 0
sum1 = 0
v.append( 0 )
# Push the prefix sum1 of the
# array arr[] in prefix[]
for i in range (N):
sum1 + = arr[i]
v.append(sum1)
l = 0
ans = 0
r = 0
for i in range ( len (v)):
# Search r for each i
r = bin1(v[i], K, N)
# Update ans
ans = max (ans, r - i)
# Print the length of subarray
# found in the array
print (ans)
# Driver Code if __name__ = = '__main__' :
# Given array arr[]
arr = [ 6 , 8 , 14 , 9 , 4 , 11 , 10 ]
N = len (arr)
# Given sum1 K
K = 13
# Function Call
findSubarraysum1K(arr, N, K)
# This code is contributed by ipg2016107 |
// C# program for the above approach using System;
using System.Collections.Generic;
class GFG {
// To store the prefix sum array
static List< int > v = new List< int >();
// Function for searching the
// lower bound of the subarray
static int bin( int val, int k, int n)
{
int lo = 0;
int hi = n;
int mid;
int ans = -1;
// Iterate until low less
// than equal to high
while (lo <= hi) {
mid = lo + (hi - lo) / 2;
// For each mid finding sum
// of sub array less than
// or equal to k
if (v[mid] - val <= k) {
lo = mid + 1;
ans = mid;
}
else
hi = mid - 1;
}
// Return the final answer
return ans;
}
// Function to find the length of
// subarray with sum K
static void findSubarraySumK( int [] arr, int N, int K)
{
// Initialize sum to 0
int sum = 0;
v.Add(0);
// Push the prefix sum of the
// array []arr in prefix[]
for ( int i = 0; i < N; i++) {
sum += arr[i];
v.Add(sum);
}
int ans = 0, r;
for ( int i = 0; i < v.Count; i++) {
// Search r for each i
r = bin(v[i], K, N);
// Update ans
ans = Math.Max(ans, r - i);
}
// Print the length of subarray
// found in the array
Console.Write(ans);
}
// Driver Code
public static void Main(String[] args)
{
// Given array []arr
int [] arr = { 6, 8, 14, 9, 4, 11, 10 };
int N = arr.Length;
// Given sum K
int K = 13;
// Function call
findSubarraySumK(arr, N, K);
}
} // This code is contributed by gauravrajput1 |
<script> // Javascript program for the above approach // To store the prefix sum array let v = []; // Function for searching the // lower bound of the subarray function bin(val, k, n)
{ let lo = 0;
let hi = n;
let mid;
let ans = -1;
// Iterate until low less
// than equal to high
while (lo <= hi) {
mid = lo + parseInt((hi - lo) / 2);
// For each mid finding sum
// of sub array less than
// or equal to k
if (v[mid] - val <= k) {
lo = mid + 1;
ans = mid;
}
else
hi = mid - 1;
}
// Return the final answer
return ans;
} // Function to find the length of // subarray with sum K function findSubarraySumK(arr, N, K)
{ // Initialize sum to 0
let sum = 0;
v.push(0);
// Push the prefix sum of the
// array arr[] in prefix[]
for (let i = 0; i < N; i++) {
sum += arr[i];
v.push(sum);
}
let l = 0, ans = 0, r;
for (let i = 0; i < N; i++) {
// Search r for each i
r = bin(v[i], K, N);
// Update ans
ans = Math.max(ans, r - i);
}
// Print the length of subarray
// found in the array
document.write(ans);
} // Driver Code // Given array arr[]
let arr = [ 6, 8, 14, 9, 4, 11, 10 ];
let N = arr.length;
// Given sum K
let K = 13;
// Function Call
findSubarraySumK(arr, N, K);
</script> |
2
Time Complexity: O(N*log2N)
Auxiliary Space: O(N)
Efficient approach: For a O(N) approach, please refer to the efficient approach of this article.
Hashmap approach in python:
Approach:
- Initialize a hashmap prefix_sum with initial key-value pair of 0: -1. The keys in this hashmap represent the prefix sum of the elements in the array till a certain index, and the values represent the index at which that prefix sum was first seen.
- Initialize curr_sum and max_len to 0.
- Traverse through the array using a loop and at each iteration, update the curr_sum by adding the current element.
- Check if curr_sum – K is present in the prefix_sum hashmap. If it is, then update max_len to be the maximum of its current value and i – prefix_sum[curr_sum – K], where i is the current index.
- Check if curr_sum is not already present in the prefix_sum hashmap. If it is not, then add a new key-value pair to the hashmap with curr_sum as the key and i as the value.
- Return max_len.
#include <iostream> #include <unordered_map> #include <vector> int LongestSubarraySum( const std::vector< int >& arr, int K) {
int n = arr.size();
std::unordered_map< int , int > prefixSum;
int currSum = 0;
int maxLen = 0;
for ( int i = 0; i < n; i++) {
currSum += arr[i];
// If (currSum - K) is in the prefixSum, update maxLen
if (prefixSum.find(currSum - K) != prefixSum.end()) {
maxLen = std::max(maxLen, i - prefixSum[currSum - K]);
}
// If currSum is not in prefixSum, add it with the current index
if (prefixSum.find(currSum) == prefixSum.end()) {
prefixSum[currSum] = i;
}
}
return maxLen;
} int main() {
// Example usage
std::vector< int > arr1 = {2, 3, 4, 2, 1, 1};
int K1 = 10;
std::cout << "Longest subarray length with sum " << K1 << " in [" ;
for ( int i = 0; i < arr1.size(); i++) {
std::cout << arr1[i];
if (i < arr1.size() - 1) {
std::cout << ", " ;
}
}
std::cout << "] is: " << LongestSubarraySum(arr1, K1) << std::endl; // Output: 4
std::vector< int > arr2 = {6, 8, 14, 9, 4, 11, 10};
int K2 = 13;
std::cout << "Longest subarray length with sum " << K2 << " in [" ;
for ( int i = 0; i < arr2.size(); i++) {
std::cout << arr2[i];
if (i < arr2.size() - 1) {
std::cout << ", " ;
}
}
std::cout << "] is: " << LongestSubarraySum(arr2, K2) << std::endl; // Output: 2
return 0;
} |
import java.util.HashMap;
import java.util.Map;
public class Main {
public static int LongestSubarraySum( int [] arr, int K) {
int n = arr.length;
Map<Integer, Integer> prefixSum = new HashMap<>();
int currSum = 0 ;
int maxLen = 0 ;
for ( int i = 0 ; i < n; i++) {
currSum += arr[i];
// If (currSum - K) is in prefixSum, update maxLen
if (prefixSum.containsKey(currSum - K)) {
maxLen = Math.max(maxLen, i - prefixSum.get(currSum - K));
}
// If currSum is not in prefixSum, add it with the current index
if (!prefixSum.containsKey(currSum)) {
prefixSum.put(currSum, i);
}
}
return maxLen;
}
public static void main(String[] args) {
// Example usage
int [] arr1 = { 2 , 3 , 4 , 2 , 1 , 1 };
int K1 = 10 ;
System.out.print( "Longest subarray length with sum " + K1 + " in [" );
for ( int i = 0 ; i < arr1.length; i++) {
System.out.print(arr1[i]);
if (i < arr1.length - 1 ) {
System.out.print( ", " );
}
}
System.out.println( "] is: " + LongestSubarraySum(arr1, K1)); // Output: 4
int [] arr2 = { 6 , 8 , 14 , 9 , 4 , 11 , 10 };
int K2 = 13 ;
System.out.print( "Longest subarray length with sum " + K2 + " in [" );
for ( int i = 0 ; i < arr2.length; i++) {
System.out.print(arr2[i]);
if (i < arr2.length - 1 ) {
System.out.print( ", " );
}
}
System.out.println( "] is: " + LongestSubarraySum(arr2, K2)); // Output: 2
}
} |
def longest_subarray_sum(arr, K):
n = len (arr)
prefix_sum = { 0 : - 1 }
curr_sum = 0
max_len = 0
for i in range (n):
curr_sum + = arr[i]
if curr_sum - K in prefix_sum:
max_len = max (max_len, i - prefix_sum[curr_sum - K])
if curr_sum not in prefix_sum:
prefix_sum[curr_sum] = i
return max_len
# example usage arr1 = [ 2 , 3 , 4 , 2 , 1 , 1 ]
K1 = 10
print ( "Longest subarray length with sum" , K1, "in" , arr1, "is:" , longest_subarray_sum(arr1, K1)) # output: 4
arr2 = [ 6 , 8 , 14 , 9 , 4 , 11 , 10 ]
K2 = 13
print ( "Longest subarray length with sum" , K2, "in" , arr2, "is:" , longest_subarray_sum(arr2, K2)) # output: 2
|
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{ static int LongestSubarraySum(List< int > arr, int K)
{
int n = arr.Count;
Dictionary< int , int > prefixSum = new Dictionary< int , int >();
int currSum = 0;
int maxLen = 0;
for ( int i = 0; i < n; i++)
{
currSum += arr[i];
// If (currSum - K) is in prefixSum, update maxLen
if (prefixSum.ContainsKey(currSum - K))
{
maxLen = Math.Max(maxLen, i - prefixSum[currSum - K]);
}
// If currSum is not in prefixSum, add it with the current index
if (!prefixSum.ContainsKey(currSum))
{
prefixSum[currSum] = i;
}
}
return maxLen;
}
static void Main()
{
// Example usage
List< int > arr1 = new List< int > { 2, 3, 4, 2, 1, 1 };
int K1 = 10;
Console.Write( "Longest subarray length with sum " + K1 + " in [" );
for ( int i = 0; i < arr1.Count; i++)
{
Console.Write(arr1[i]);
if (i < arr1.Count - 1)
{
Console.Write( ", " );
}
}
Console.WriteLine( "] is: " + LongestSubarraySum(arr1, K1)); // Output: 4
List< int > arr2 = new List< int > { 6, 8, 14, 9, 4, 11, 10 };
int K2 = 13;
Console.Write( "Longest subarray length with sum " + K2 + " in [" );
for ( int i = 0; i < arr2.Count; i++)
{
Console.Write(arr2[i]);
if (i < arr2.Count - 1)
{
Console.Write( ", " );
}
}
Console.WriteLine( "] is: " + LongestSubarraySum(arr2, K2)); // Output: 2
}
} |
// Javascript Code function LongestSubarraySum(arr, K) {
let n = arr.length;
let prefixSum = new Map();
let currSum = 0;
let maxLen = 0;
for (let i = 0; i < n; i++) {
currSum += arr[i];
// If (currSum - K) is in prefixSum, update maxLen
if (prefixSum.has(currSum - K)) {
maxLen = Math.max(maxLen, i - prefixSum.get(currSum - K));
}
// If currSum is not in prefixSum, add it with the current index
if (!prefixSum.has(currSum)) {
prefixSum.set(currSum, i);
}
}
return maxLen;
} // Example usage let arr1 = [2, 3, 4, 2, 1, 1]; let K1 = 10; console.log(`Longest subarray length with sum ${K1} in [${arr1}] is: ${LongestSubarraySum(arr1, K1)}`); // Output: 4
let arr2 = [6, 8, 14, 9, 4, 11, 10]; let K2 = 13; console.log(`Longest subarray length with sum ${K2} in [${arr2}] is: ${LongestSubarraySum(arr2, K2)}`); // Output: 2
|
Longest subarray length with sum 10 in [2, 3, 4, 2, 1, 1] is: 4 Longest subarray length with sum 13 in [6, 8, 14, 9, 4, 11, 10] is: 2
The time complexity of this approach is O(n) as we are traversing through the array only once,
the space complexity is O(n) as we are using a hashmap to store prefix sums.