Longest subarray having sum K | Set 2
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++
#include <bits/stdc++.h>
using namespace std;
vector< int > v;
int bin( int val, int k, int n)
{
int lo = 0;
int hi = n;
int mid;
int ans = -1;
while (lo <= hi) {
mid = lo + (hi - lo) / 2;
if (v[mid] - val <= k) {
lo = mid + 1;
ans = mid;
}
else
hi = mid - 1;
}
return ans;
}
void findSubarraySumK( int arr[], int N, int K)
{
int sum = 0;
v.push_back(0);
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++) {
r = bin(v[i], K, N);
ans = max(ans, r - i);
}
cout << ans;
}
int main()
{
int arr[] = { 6, 8, 14, 9, 4, 11, 10 };
int N = sizeof (arr) / sizeof (arr[0]);
int K = 13;
findSubarraySumK(arr, N, K);
return 0;
}
|
Java
import java.util.*;
class GFG {
static Vector<Integer> v = new Vector<Integer>();
static int bin( int val, int k, int n)
{
int lo = 0 ;
int hi = n;
int mid;
int ans = - 1 ;
while (lo <= hi) {
mid = lo + (hi - lo) / 2 ;
if (v.get(mid) - val <= k) {
lo = mid + 1 ;
ans = mid;
}
else
hi = mid - 1 ;
}
return ans;
}
static void findSubarraySumK( int arr[], int N, int K)
{
int sum = 0 ;
v.add( 0 );
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++) {
r = bin(v.get(i), K, N);
ans = Math.max(ans, r - i);
}
System.out.print(ans);
}
public static void main(String[] args)
{
int arr[] = { 6 , 8 , 14 , 9 , 4 , 11 , 10 };
int N = arr.length;
int K = 13 ;
findSubarraySumK(arr, N, K);
}
}
|
Python3
v = []
def bin1(val, k, n):
global v
lo = 0
hi = n
mid = 0
ans = - 1
while (lo < = hi):
mid = lo + ((hi - lo) / / 2 )
if (v[mid] - val < = k):
lo = mid + 1
ans = mid
else :
hi = mid - 1
return ans
def findSubarraysum1K(arr, N, K):
global v
sum1 = 0
v.append( 0 )
for i in range (N):
sum1 + = arr[i]
v.append(sum1)
l = 0
ans = 0
r = 0
for i in range ( len (v)):
r = bin1(v[i], K, N)
ans = max (ans, r - i)
print (ans)
if __name__ = = '__main__' :
arr = [ 6 , 8 , 14 , 9 , 4 , 11 , 10 ]
N = len (arr)
K = 13
findSubarraysum1K(arr, N, K)
|
C#
using System;
using System.Collections.Generic;
class GFG {
static List< int > v = new List< int >();
static int bin( int val, int k, int n)
{
int lo = 0;
int hi = n;
int mid;
int ans = -1;
while (lo <= hi) {
mid = lo + (hi - lo) / 2;
if (v[mid] - val <= k) {
lo = mid + 1;
ans = mid;
}
else
hi = mid - 1;
}
return ans;
}
static void findSubarraySumK( int [] arr, int N, int K)
{
int sum = 0;
v.Add(0);
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++) {
r = bin(v[i], K, N);
ans = Math.Max(ans, r - i);
}
Console.Write(ans);
}
public static void Main(String[] args)
{
int [] arr = { 6, 8, 14, 9, 4, 11, 10 };
int N = arr.Length;
int K = 13;
findSubarraySumK(arr, N, K);
}
}
|
Javascript
<script>
let v = [];
function bin(val, k, n)
{
let lo = 0;
let hi = n;
let mid;
let ans = -1;
while (lo <= hi) {
mid = lo + parseInt((hi - lo) / 2);
if (v[mid] - val <= k) {
lo = mid + 1;
ans = mid;
}
else
hi = mid - 1;
}
return ans;
}
function findSubarraySumK(arr, N, K)
{
let sum = 0;
v.push(0);
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++) {
r = bin(v[i], K, N);
ans = Math.max(ans, r - i);
}
document.write(ans);
}
let arr = [ 6, 8, 14, 9, 4, 11, 10 ];
let N = arr.length;
let K = 13;
findSubarraySumK(arr, N, K);
</script>
|
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.
C++
#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 (prefixSum.find(currSum - K) != prefixSum.end()) {
maxLen = std::max(maxLen, i - prefixSum[currSum - K]);
}
if (prefixSum.find(currSum) == prefixSum.end()) {
prefixSum[currSum] = i;
}
}
return maxLen;
}
int main() {
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;
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;
return 0;
}
|
Java
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 (prefixSum.containsKey(currSum - K)) {
maxLen = Math.max(maxLen, i - prefixSum.get(currSum - K));
}
if (!prefixSum.containsKey(currSum)) {
prefixSum.put(currSum, i);
}
}
return maxLen;
}
public static void main(String[] args) {
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));
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));
}
}
|
Python3
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
arr1 = [ 2 , 3 , 4 , 2 , 1 , 1 ]
K1 = 10
print ( "Longest subarray length with sum" , K1, "in" , arr1, "is:" , longest_subarray_sum(arr1, K1))
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))
|
C#
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 (prefixSum.ContainsKey(currSum - K))
{
maxLen = Math.Max(maxLen, i - prefixSum[currSum - K]);
}
if (!prefixSum.ContainsKey(currSum))
{
prefixSum[currSum] = i;
}
}
return maxLen;
}
static void Main()
{
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));
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));
}
}
|
Javascript
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 (prefixSum.has(currSum - K)) {
maxLen = Math.max(maxLen, i - prefixSum.get(currSum - K));
}
if (!prefixSum.has(currSum)) {
prefixSum.set(currSum, i);
}
}
return maxLen;
}
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)}`);
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
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.
Last Updated :
29 Nov, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...