Longest subarray with sum divisible by K
Given an arr[] containing n integers and a positive integer k. The problem is to find the longest subarray’s length with the sum of the elements divisible by the given value k.
Examples:
Input: arr[] = {2, 7, 6, 1, 4, 5}, k = 3
Output: 4
Explanation: The subarray is {7, 6, 1, 4} with sum 18, which is divisible by 3.Input: arr[] = {-2, 2, -5, 12, -11, -1, 7}, k = 3
Output: 5
Method 1 (Naive Approach): Consider all the subarrays and return the length of the subarray with a sum divisible by k that has the longest length.
C++
// C++ implementation to find the longest subarray // with sum divisible by k #include <bits/stdc++.h> using namespace std; // function to find the longest subarray // with sum divisible by k int longestSubarrWthSumDivByK( int arr[], int N, int k) { int maxl=0; for ( int i=0;i<N;i++) { int sum1 = 0; for ( int j=i;j<N;j++) { sum1+=arr[j]; if (sum1 % k == 0) { maxl = max(maxl , j - i + 1); } } } return maxl; } // Driver code int main() { int arr[] = { 2, 7, 6, 1, 4, 5 }; int n = sizeof (arr) / sizeof (arr[0]); int k = 3; cout << "Length = " << longestSubarrWthSumDivByK(arr, n, k); return 0; } // This code is contributed by Arpit Jain |
Java
import java.util.*; class GFG { // function to find the longest subarray // with sum divisible by k static int longestSubarrWthSumDivByK( int arr[], int N, int k) { int maxl = 0 ; for ( int i = 0 ; i < N; i++) { int sum1 = 0 ; for ( int j = i; j < N; j++) { sum1 += arr[j]; if (sum1 % k == 0 ) maxl = Math.max(maxl, j - i + 1 ); } } return maxl; } // Driver code public static void main(String[] args) { int arr[] = { 2 , 7 , 6 , 1 , 4 , 5 }; int n = arr.length; int k = 3 ; System.out.println( "Length = " + longestSubarrWthSumDivByK(arr, n, k)); } } // This code is contributed by Ajax |
C#
// C# implementation to find the longest subarray // with sum divisible by k using System; class GFG { // function to find the longest subarray // with sum divisible by k static int longestSubarrWthSumDivByK( int [] arr, int N, int k) { int maxl = 0; for ( int i = 0; i < N; i++) { int sum1 = 0; for ( int j = i; j < N; j++) { sum1 += arr[j]; if (sum1 % k == 0) maxl = Math.Max(maxl, j - i + 1); } } return maxl; } // Driver code public static void Main( string [] args) { int [] arr = { 2, 7, 6, 1, 4, 5 }; int n = arr.Length; int k = 3; Console.WriteLine( "Length = " + longestSubarrWthSumDivByK(arr, n, k)); } } // This code is contributed by Karandeep1234 |
Python3
# Python3 implementation to find the longest subarray # with sum divisible by k def longestSubarrWthSumDivByK(arr, N, k): maxl = 0 for i in range (N): sum1 = 0 for j in range (i, N): sum1 + = arr[j] if sum1 % k = = 0 : maxl = max (maxl, j - i + 1 ) return maxl # Driver code arr = [ 2 , 7 , 6 , 1 , 4 , 5 ] n = len (arr) k = 3 print ( "Length =" , longestSubarrWthSumDivByK(arr, n, k)) |
Javascript
// JavaScript implementation to find the longest subarray // with sum divisible by k function longestSubarrWthSumDivByK(arr, N, k) { let maxl = 0; for (let i = 0; i < N; i++) { let sum1 = 0; for (let j = i; j < N; j++) { sum1 += arr[j]; if (sum1 % k === 0) { maxl = Math.max(maxl, j - i + 1); } } } return maxl; } // Driver code let arr = [ 2, 7, 6, 1, 4, 5 ]; let N = arr.length; let k = 3; console.log( "Length = " + longestSubarrWthSumDivByK(arr, N, k)); //This code is contributed by dhanshri borse |
Length = 4
Time Complexity: O(n2).
Auxiliary Space: O(1)
Method 2 (Efficient Approach): Create an array mod_arr[] where mod_arr[i] stores (sum(arr[0]+arr[1]..+arr[i]) % k). Create a hash table having tuple as (ele, i), where ele represents an element of mod_arr[] and i represents the element’s index of first occurrence in mod_arr[]. Now, traverse mod_arr[] from i = 0 to n and follow the steps given below.
- If mod_arr[i] == 0, then update max_len = (i + 1).
- Else if mod_arr[i] is not present in the hash table, then create tuple (mod_arr[i], i) in the hash table.
- Else, get the hash table’s value associated with mod_arr[i]. Let this be i.
- If maxLen < (i – idx), then update max_len = (i – idx).
- Finally, return max_len.
Below is the implementation of the above approach:
C++
// C++ implementation to find the longest subarray // with sum divisible by k #include <bits/stdc++.h> using namespace std; // function to find the longest subarray // with sum divisible by k int longestSubarrWthSumDivByK( int arr[], int n, int k) { // unordered map 'um' implemented as // hash table unordered_map< int , int > um; // 'mod_arr[i]' stores (sum[0..i] % k) int mod_arr[n], max_len = 0; int curr_sum = 0; // traverse arr[] and build up the // array 'mod_arr[]' for ( int i = 0; i < n; i++) { curr_sum += arr[i]; // as the sum can be negative, taking modulo twice mod_arr[i] = ((curr_sum % k) + k) % k; // if true then sum(0..i) is divisible by k if (mod_arr[i] == 0) // update 'max' max_len = i + 1; // if value 'mod_arr[i]' not present in 'um' // then store it in 'um' with index of its // first occurrence else if (um.find(mod_arr[i]) == um.end()) um[mod_arr[i]] = i; else // if true, then update 'max' if (max_len < (i - um[mod_arr[i]])) max_len = i - um[mod_arr[i]]; } // return the required length of longest subarray // with sum divisible by 'k' return max_len; } // Driver code int main() { int arr[] = { 2, 7, 6, 1, 4, 5 }; int n = sizeof (arr) / sizeof (arr[0]); int k = 3; cout << "Length = " << longestSubarrWthSumDivByK(arr, n, k); return 0; } // Code updated by Kshitij Dwivedi |
Java
// Java implementation to find the longest // subarray with sum divisible by k import java.io.*; import java.util.*; class GfG { // function to find the longest subarray // with sum divisible by k static int longestSubarrWthSumDivByK( int arr[], int n, int k) { // unordered map 'um' implemented as // hash table HashMap<Integer, Integer> um = new HashMap<Integer, Integer>(); // 'mod_arr[i]' stores (sum[0..i] % k) int mod_arr[] = new int [n]; int max_len = 0 ; int curr_sum = 0 ; // traverse arr[] and build up the // array 'mod_arr[]' for ( int i = 0 ; i < n; i++) { curr_sum += arr[i]; // as the sum can be negative, // taking modulo twice mod_arr[i] = ((curr_sum % k) + k) % k; // if true then sum(0..i) is // divisible by k if (mod_arr[i] == 0 ) // update 'max' max_len = i + 1 ; // if value 'mod_arr[i]' not present in 'um' // then store it in 'um' with index of its // first occurrence else if (um.containsKey(mod_arr[i]) == false ) um.put(mod_arr[i], i); else // if true, then update 'max' if (max_len < (i - um.get(mod_arr[i]))) max_len = i - um.get(mod_arr[i]); } // return the required length of longest subarray // with sum divisible by 'k' return max_len; } public static void main(String[] args) { int arr[] = { 2 , 7 , 6 , 1 , 4 , 5 }; int n = arr.length; int k = 3 ; System.out.println( "Length = " + longestSubarrWthSumDivByK(arr, n, k)); } } // This code is contributed by Gitanjali, updated by Kshitij // Dwivedi |
Python3
# Python3 implementation to find the # longest subarray with sum divisible by k # Function to find the longest # subarray with sum divisible by k def longestSubarrWthSumDivByK(arr, n, k): # unordered map 'um' implemented # as hash table um = {} # 'mod_arr[i]' stores (sum[0..i] % k) mod_arr = [ 0 for i in range (n)] max_len = 0 curr_sum = 0 # Traverse arr[] and build up # the array 'mod_arr[]' for i in range (n): curr_sum + = arr[i] # As the sum can be negative, # taking modulo twice mod_arr[i] = ((curr_sum % k) + k) % k # If true then sum(0..i) is # divisible by k if (mod_arr[i] = = 0 ): # Update 'max_len' max_len = i + 1 # If value 'mod_arr[i]' not present in # 'um' then store it in 'um' with index # of its first occurrence elif (mod_arr[i] not in um): um[mod_arr[i]] = i else : # If true, then update 'max_len' if (max_len < (i - um[mod_arr[i]])): max_len = i - um[mod_arr[i]] # Return the required length of longest subarray # with sum divisible by 'k' return max_len # Driver Code if __name__ = = '__main__' : arr = [ 2 , 7 , 6 , 1 , 4 , 5 ] n = len (arr) k = 3 print ( "Length =" , longestSubarrWthSumDivByK(arr, n, k)) # This code is contributed by Surendra_Gangwar, updated by Kshitij Dwivedi |
C#
using System; using System.Collections.Generic; // C# implementation to find the longest // subarray with sum divisible by k public class GfG { // function to find the longest subarray // with sum divisible by k public static int longestSubarrWthSumDivByK( int [] arr, int n, int k) { // unordered map 'um' implemented as // hash table Dictionary< int , int > um = new Dictionary< int , int >(); // 'mod_arr[i]' stores (sum[0..i] % k) int [] mod_arr = new int [n]; int max_len = 0; int curr_sum = 0; // traverse arr[] and build up the // array 'mod_arr[]' for ( int i = 0; i < n; i++) { curr_sum += arr[i]; // as the sum can be negative, // adjusting and calculating modulo twice mod_arr[i] = ((curr_sum % k) + k) % k; // if true then sum(0..i) is // divisible by k if (mod_arr[i] == 0) { // update 'max_len' max_len = i + 1; } // if value 'mod_arr[i]' not present in 'um' // then store it in 'um' with index of its // first occurrence else if (um.ContainsKey(mod_arr[i]) == false ) { um[mod_arr[i]] = i; } else { // if true, then update 'max_len' if (max_len < (i - um[mod_arr[i]])) { max_len = i - um[mod_arr[i]]; } } } // return the required length of longest subarray // with sum divisible by 'k' return max_len; } public static void Main( string [] args) { int [] arr = new int [] { 2, 7, 6, 1, 4, 5 }; int n = arr.Length; int k = 3; Console.WriteLine( "Length = " + longestSubarrWthSumDivByK(arr, n, k)); } } // This code is contributed by Shrikant13, updated by // Kshitij Dwivedi |
Javascript
<script> // Javascript implementation to find the longest subarray // with sum divisible by k // function to find the longest subarray // with sum divisible by k function longestSubarrWthSumDivByK(arr, n, k) { // unordered map 'um' implemented as // hash table var um = new Map(); // 'mod_arr[i]' stores (sum[0..i] % k) var mod_arr = Array(n), max_len = 0; var curr_sum = 0; // traverse arr[] and build up the // array 'mod_arr[]' for ( var i = 0; i < n; i++) { curr_sum += arr[i]; // as the sum can be negative, taking modulo twice mod_arr[i] = ((curr_sum % k) + k) % k; // if true then sum(0..i) is divisible // by k if (mod_arr[i] == 0) // update 'max_len' max_len = i + 1; // if value 'mod_arr[i]' not present in 'um' // then store it in 'um' with index of its // first occurrence else if (!um.has(mod_arr[i])) um.set(mod_arr[i] , i); else // if true, then update 'max_len' if (max_len < (i - um.get(mod_arr[i]))) max_len = i - um.get(mod_arr[i]); } // return the required length of longest subarray with // sum divisible by 'k' return max_len; } // Driver program to test above var arr = [2, 7, 6, 1, 4, 5]; var n = arr.length; var k = 3; document.write( "Length = " + longestSubarrWthSumDivByK(arr, n, k)); // This code is contributed by rrrtnx, and updated by Kshitij Dwivedi </script> |
Length = 4
Time Complexity: O(n), as we traverse the input array only once.
Auxiliary Space: O(n + k), O(n) for mod_arr[], and O(k) for storing the remainder values in the hash table.
Space Optimized approach: The space optimization for the above approach to O(n) Instead of keeping a separate array to store the modulus of all values, we compute it on the go and store remainders in the hash table.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h> using namespace std; // function to find the longest subarray // with sum divisible by k int longestSubarrWthSumDivByK( int arr[], int n, int k) { // unordered map 'um' implemented as // hash table unordered_map< int , int > um; int max_len = 0; int curr_sum = 0; for ( int i = 0; i < n; i++) { curr_sum += arr[i]; int mod = ((curr_sum % k) + k) % k; // if true then sum(0..i) is divisible // by k if (mod == 0) // update 'max_len' max_len = i + 1; // if value 'mod_arr[i]' not present in 'um' // then store it in 'um' with index of its // first occurrence else if (um.find(mod) == um.end()) um[mod] = i; else // if true, then update 'max_len' if (max_len < (i - um[mod])) max_len = i - um[mod]; } // return the required length of longest subarray with // sum divisible by 'k' return max_len; } // Driver code int main() { int arr[] = { 2, 7, 6, 1, 4, 5 }; int n = sizeof (arr) / sizeof (arr[0]); int k = 3; cout << "Length = " << longestSubarrWthSumDivByK(arr, n, k); return 0; } // Code Updated by Kshitij Dwivedi |
Java
/*package whatever //do not write package name here */ import java.io.*; import java.util.*; class GFG { static int longestSubarrWthSumDivByK( int arr[], int n, int k) { Map<Integer, Integer> map = new HashMap<>(); int max_len = 0 ; int sum = 0 ; for ( int i = 0 ; i < n; i++) { sum += arr[i]; // to handle negative values as well int mod = ((sum % k) + k) % k; if (mod == 0 ) max_len = i + 1 ; if (!map.containsKey(mod)) map.put(mod, i); else { int sz = i - map.get(mod); max_len = Math.max(max_len, sz); } } return max_len; } public static void main(String[] args) { int arr[] = { 2 , 7 , 6 , 1 , 4 , 5 }; int n = arr.length; int k = 3 ; System.out.println( "Length = " + longestSubarrWthSumDivByK(arr, n, k)); } } // Updated By Kshitij Dwivedi |
Python3
# function to find the longest subarray # with sum divisible by k def longestSubarrWthSumDivByK(arr, n, k): # unordered map 'um' implemented as # hash table um = {} max_len = 0 curr_sum = 0 for i in range (n): curr_sum + = arr[i] mod = ((curr_sum % k) + k) % k # if true then sum(0..i) is divisible by k if mod = = 0 : # update 'max_len' max_len = i + 1 # if value 'mod_arr[i]' not present in 'um' # then store it in 'um' with index of its # first occurrence elif mod in um.keys(): if max_len < (i - um[mod]): max_len = i - um[mod] else : um[mod] = i # return the required length of longest subarray with # sum divisible by 'k' return max_len arr = [ 2 , 7 , 6 , 1 , 4 , 5 ] n = len (arr) k = 3 print ( "Length =" , longestSubarrWthSumDivByK(arr, n, k)) # This code is contributed by amreshkumar3, and updated by Kshitij Dwivedi |
C#
using System; using System.Collections.Generic; // C# implementation to find the longest // subarray with sum divisible by k public class GFG { public static int longestSubarrWthSumDivByK( int [] arr, int n, int k) { // unordered map 'um' implemented as // hash table Dictionary< int , int > um = new Dictionary< int , int >(); int max_len = 0; int curr_sum = 0; for ( int i = 0; i < n; i++) { curr_sum += arr[i]; int mod = ((curr_sum % k) + k) % k; // if true then sum(0..i) is divisible // by k if (mod == 0) // update 'max_len' { max_len = i + 1; } // if value 'mod' not present in 'um' // then store it in 'um' with index of its // first occurrence else if (um.ContainsKey(mod) == false ) { um[mod] = i; } else { // if true, then update 'max' if (max_len < (i - um[mod])) { max_len = i - um[mod]; } } } // return the required length of longest subarray // with sum divisible by 'k' return max_len; } public static void Main( string [] args) { int [] arr = new int [] { 2, 7, 6, 1, 4, 5 }; int n = arr.Length; int k = 3; Console.WriteLine( "Length = " + longestSubarrWthSumDivByK(arr, n, k)); } } // This code is contributed by ishankhandelwals and updated // by Kshitij Dwivedi |
Javascript
<script> // function to find the longest subarray // with sum divisible by k function longestSubarrWthSumDivByK(arr,n,k) { // map 'um' implemented as // hash table let um = new Map(); let max_len = 0; let curr_sum = 0; for (let i = 0; i < n; i++) { curr_sum += arr[i]; let mod = ((curr_sum % k) + k) % k; // if true then sum(0..i) is divisible // by k if (mod == 0) // update 'max_len' max_len = i + 1; // if value 'mod_arr[i]' not present in 'um' // then store it in 'um' with index of its // first occurrence else if (um.has(mod) == false ) um.set(mod,i); else // if true, then update 'max' if (max_len < (i - um.get(mod))) max_len = i - um.get(mod); } // required length of longest subarray with // sum divisible by 'k' return max_len; } // Driver program to test above let arr = [2, 7, 6, 1, 4, 5]; let n = arr.length; let k = 3; document.write( "Length = " + longestSubarrWthSumDivByK(arr, n, k)); // This code is contributed by shinjanpatra, and updated by Kshitij Dwivedi. </script> |
Length = 4
Time Complexity: O(n), as we traverse the input array only once.
Auxiliary Space: O(min(n,k))
Please Login to comment...