Open In App

JavaScript Program to Find Largest Subarray with a Sum Divisible by k

Last Updated : 29 Aug, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Finding the largest subarray with a sum divisible by a given integer 'k' is a common problem in JavaScript and other programming languages. This task involves identifying a contiguous subarray within an array of integers such that the sum of its elements is divisible by 'k' and is as long as possible. This problem is essential in various scenarios, including optimizing algorithms and data processing.

Examples:

Input: arr[] = {7,1,3,2,9} , k = 3
Output: 4
Explanation: The subarray is {1, 3, 2, 9} with sum 15, which is divisible by 3.
Input: arr[] = { 4, 5}, k = 2
Output: 1

Approach 1: Brute Force Approach

The brute force approach involves generating all possible subarrays and calculating their sums. For each sum, check if it's divisible by 'k' and keep track of the largest subarray found so far.

Example:

JavaScript
function largestSubarraySumDivisibleByK(arr, k) {
    let maxLength = 0;

    for (let start = 0;
        start < arr.length; start++) {
        let currentSum = 0;

        for (let end = start;
            end < arr.length; end++) {
            currentSum += arr[end];

            if (currentSum % k === 0 &&
                (end - start + 1) > maxLength) {
                maxLength = end - start + 1;
            }
        }
    }

    return maxLength;
}

const arr = [7, 1, 3, 2, 9];
const k = 3;
console.log(largestSubarraySumDivisibleByK(arr, k)); 

Output
4

Approach 2: Using Prefix Sum

We can use prefix sums to efficiently calculate subarray sums. By storing the cumulative sum of elements up to each position, you can quickly determine the sum of any subarray. To find the largest subarray divisible by 'k', you track the prefix sums modulo 'k' and store the indices where each remainder is first encountered.

JavaScript
function largestSubarraySumDivisibleByK(arr, k) {
    const prefixSums = [0];
    let currentSum = 0;
    let maxLength = 0;

    for (let num of arr) {
        currentSum = (currentSum + num) % k;
        prefixSums.push(currentSum);
    }

    const remainderIndices = {};

    for (let i = 0; i < prefixSums.length; i++) {
        if (remainderIndices
            .hasOwnProperty(prefixSums[i])) {
            maxLength = Math.max(maxLength,
                i - remainderIndices[prefixSums[i]]);
        } else {
            remainderIndices[prefixSums[i]] = i;
        }
    }

    return maxLength;
}

const arr = [7, 1, 3, 2, 9];
const k = 3;
console.log(largestSubarraySumDivisibleByK(arr, k));

Output
4

Approach 3: Using a Hash Map

An efficient approach involves using a hash map to store the prefix sums modulo 'k' and their corresponding indices.

JavaScript
function largestSubarraySumDivisibleByK(arr, k) {
    let currentSum = 0;
    let maxLength = 0;
    const remainderIndices = { 0: -1 };

    for (let i = 0; i < arr.length; i++) {
        currentSum += arr[i];
        const remainder = (currentSum % k + k) % k;

        if (remainderIndices
            .hasOwnProperty(remainder)) {
            maxLength = Math.max(maxLength,
                i - remainderIndices[remainder]);
        } else {
            remainderIndices[remainder] = i;
        }
    }

    return maxLength;
}

const arr = [7, 1, 3, 2, 9];
const k = 3;
console.log(largestSubarraySumDivisibleByK(arr, k));

Output
4

Approach 4: Using Sliding Window Technique

In this approach, we use a sliding window to find the largest subarray whose sum is divisible by a given integer 'k'. The sliding window technique involves maintaining a window of elements and adjusting its size dynamically as we iterate through the array. This approach is particularly useful for handling continuous data streams or when you need to keep track of a specific condition dynamically.

Example: Here is the implementation of the sliding window approach to find the largest subarray with a sum divisible by 'k'.

JavaScript
function largestSubarrayDivisibleByK(arr, k) {
    let maxLength = 0;
    let currentSum = 0;

    // Create a map to store the first occurrence of remainders
    let remainderMap = new Map();
    remainderMap.set(0, -1);

    for (let i = 0; i < arr.length; i++) {
        currentSum += arr[i];
        
        // Get the remainder of the current sum
        let remainder = ((currentSum % k) + k) % k;

        // If this remainder was seen before, update the maxLength
        if (remainderMap.has(remainder)) {
            maxLength = Math.max(maxLength, i - remainderMap.get(remainder));
        } else {
            // Store the first occurrence of this remainder
            remainderMap.set(remainder, i);
        }
    }

    return maxLength;
}

// Example usage:
const arr1 = [7, 1, 3, 2, 9];
const k1 = 3;
console.log(largestSubarrayDivisibleByK(arr1, k1)); // Output: 4

const arr2 = [4, 5];
const k2 = 2;
console.log(largestSubarrayDivisibleByK(arr2, k2)); // Output: 1

Output
4
1

Approach 5: Two-Pointer Technique

  1. Prefix Sums with Modulo: Calculate prefix sums and use modulo operations to determine if a subarray's sum is divisible by k.
  2. Two Pointers: Use two pointers to find the longest subarray where the sum is divisible by k. The left pointer marks the start of the subarray, and the right pointer expands the subarray.

Steps:

  1. Calculate Prefix Sums: Calculate cumulative sums and their modulo k.
  2. Expand and Contract: Use two pointers to maintain a subarray where the sum modulo k is zero, adjusting pointers based on conditions.

Example:

JavaScript
function largestSubarrayDivisibleByK(arr, k) {
    let n = arr.length;
    let maxLength = 0;
    let prefixSum = 0;
    let remainderMap = new Map();
    remainderMap.set(0, -1);

    for (let i = 0; i < n; i++) {
        prefixSum += arr[i];
        let remainder = ((prefixSum % k) + k) % k;
        if (remainderMap.has(remainder)) {
            maxLength = Math.max(maxLength, i - remainderMap.get(remainder));
        } else {
            remainderMap.set(remainder, i);
        }
    }

    return maxLength;
}
const arr1 = [7, 1, 3, 2, 9];
const k1 = 3;
console.log(largestSubarrayDivisibleByK(arr1, k1)); 

const arr2 = [4, 5];
const k2 = 2;
console.log(largestSubarrayDivisibleByK(arr2, k2));

Output
4
1



Next Article

Similar Reads