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++
// 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
// 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
# 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#
// 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 |
Javascript
<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.
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 # 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 |
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.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!