Open In App

Minimum Removals for Target Sum

Last Updated : 23 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array of positive integers arr[] and an integer k, you can remove either the leftmost or rightmost element from the array in one operation. After each operation, the size of arr[] is reduced by one. The task is to find the minimum number of operations required to make the total sum of the removed elements exactly equal to k. If it is impossible to achieve the sum k, return -1.

Examples : 

Input: arr[] = [3, 4, 1, 3, 2], k = 5
Output: 2
Explanation: Removing 3 from left and 2 from right gives a sum of 5 in 2 operations.

Input: arr[] = [5, 3, 4, 6, 2], k = 6
Output: -1
Explanation: It is impossible to achieve the sum of removed elements as 6.

Input: arr[] = [1, 1, 3, 1, 2], k = 4
Output: 3
Explanation: Removing 1, 1 from left and 2 from right gives a sum of 4 in 3 operations.

[Naive Approach] Recursive Approach - O(2 ^ n) Time and O(n) Space

The idea is to use recursion to explore all combinations of removing elements from the left or right. In each recursive call, we have two choices: either to remove the left most element or remove the right most element. After exploring both the choices, return the minimum of the two. If all elements are exhausted, return -1.

C++
// Recursive C++ code for minimum removals for target sum

#include <climits>
#include <iostream>
#include <vector>
using namespace std;

int minRemovalsRec(vector<int> &arr, int k, int left, int right, int cnt) {
    
    // Target sum achieved
    if (k == 0)
        return cnt; 
  
    // No elements left
    if (left > right)
        return INT_MAX; 

    // remove leftmost element
    int l = minRemovalsRec(arr, k - arr[left], left + 1, right, cnt + 1);
  
    // Remove rightmost element
    int r = minRemovalsRec(arr, k - arr[right], left, right - 1, cnt + 1);

    return min(l, r);
}

int minRemovals(vector<int> &arr, int k) {
    int res = minRemovalsRec(arr, k, 0, arr.size() - 1, 0);
    return res == INT_MAX ? -1 : res;
}

int main() {
    vector<int> arr = {3, 4, 1, 3, 2};
    int k = 5;
    cout << minRemovals(arr, k) << endl;
    return 0;
}
C
// Recursive C code for minimum removals for target sum

#include <limits.h>
#include <stdio.h>

int minRemovalsRec(int arr[], int k, int left, int right, int cnt) {
    
    // Target sum achieved
    if (k == 0)
        return cnt; 

    // No elements left
    if (left > right)
        return INT_MAX; 

    // Remove leftmost element
    int l = minRemovalsRec(arr, k - arr[left], left + 1, right, cnt + 1);

    // Remove rightmost element
    int r = minRemovalsRec(arr, k - arr[right], left, right - 1, cnt + 1);

    return (l < r) ? l : r;
}

int minRemovals(int arr[], int k, int n) {
    int res = minRemovalsRec(arr, k, 0, n - 1, 0);
    return res == INT_MAX ? -1 : res;
}

int main() {
    int arr[] = {3, 4, 1, 3, 2};
    int k = 5;
    int n = sizeof(arr) / sizeof(arr[0]);
    printf("%d\n", minRemovals(arr, k, n));
    return 0;
}
Java
// Recursive Java code for minimum removals for target sum

import java.util.*;
class GfG {

    // Recursive method for minimum removals for target sum
    static int minRemovalsRec(int[] arr, int k, int left, int right, int cnt) {

        // Target sum achieved
        if (k == 0)
            return cnt;

        // No elements left
        if (left > right)
            return Integer.MAX_VALUE;

        // Remove leftmost element
        int l = minRemovalsRec(arr, k - arr[left], left + 1, right, cnt + 1);

        // Remove rightmost element
        int r = minRemovalsRec(arr, k - arr[right], left, right - 1, cnt + 1);

        return Math.min(l, r);
    }

    static int minRemovals(int[] arr, int k) {
        int res = minRemovalsRec(arr, k, 0, arr.length - 1, 0);
        return res == Integer.MAX_VALUE ? -1 : res;
    }

    public static void main(String[] args) {
        int[] arr = {3, 4, 1, 3, 2};
        int k = 5;
        System.out.println(minRemovals(arr, k));
    }
}
Python
# Recursive Python3 code for minimum removals for target sum

def minRemovalsRec(arr, k, left, right, cnt):

    # Target sum achieved
    if k == 0:
        return cnt

    # No elements left
    if left > right:
        return float('inf')

    # Remove leftmost element
    l = minRemovalsRec(arr, k - arr[left], left + 1, right, cnt + 1)

    # Remove rightmost element
    r = minRemovalsRec(arr, k - arr[right], left, right - 1, cnt + 1)

    return min(l, r)

def minRemovals(arr, k):
    res = minRemovalsRec(arr, k, 0, len(arr) - 1, 0)
    return -1 if res == float('inf') else res

if __name__ == "__main__":
    arr = [3, 4, 1, 3, 2]
    k = 5
    print(minRemovals(arr, k))
C#
// Recursive C# code for minimum removals for target sum

using System;
class GfG {
  
    // Recursive method for minimum removals for target sum
    static int MinRemovalsRec(int[] arr, int k, int left, int right, int cnt) {
        
        // Target sum achieved
        if (k == 0)
            return cnt;

        // No elements left
        if (left > right)
            return int.MaxValue;

        // Remove leftmost element
        int l = MinRemovalsRec(arr, k - arr[left], left + 1, right, cnt + 1);

        // Remove rightmost element
        int r = MinRemovalsRec(arr, k - arr[right], left, right - 1, cnt + 1);

        return Math.Min(l, r);
    }

    static int MinRemovals(int[] arr, int k) {
        int res = MinRemovalsRec(arr, k, 0, arr.Length - 1, 0);
        return res == int.MaxValue ? -1 : res;
    }

    static void Main() {
        int[] arr = { 3, 4, 1, 3, 2 };
        int k = 5;
        Console.WriteLine(MinRemovals(arr, k));
    }
}
JavaScript
// Recursive JS code for minimum removals for target sum

function minRemovalsRec(arr, k, left, right, cnt) {

    // Target sum achieved
    if (k === 0)
        return cnt;

    // No elements left
    if (left > right)
        return Number.MAX_SAFE_INTEGER;

    // Remove leftmost element
    let l = minRemovalsRec(arr, k - arr[left], left + 1, right, cnt + 1);

    // Remove rightmost element
    let r = minRemovalsRec(arr, k - arr[right], left, right - 1, cnt + 1);

    return Math.min(l, r);
}

function minRemovals(arr, k) {
    let res = minRemovalsRec(arr, k, 0, arr.length - 1, 0);
    return res === Number.MAX_SAFE_INTEGER ? -1 : res;
}

// Driver Code
const arr = [3, 4, 1, 3, 2];
const k = 5;
console.log(minRemovals(arr, k));

Output
2

[Better Approach] Using Prefix Array - O(n) Time and O(n) Space

If we observe carefully, we can say that after removing the elements whose sum = k, the sum of the remaining elements will be (total sum - k). Since we need to minimize the removals, the problem can be reduced to finding the longest subarray whose sum = (total sum - k).

We can find the longest subarray having sum = (total sum - k) by using a hash map or dictionary to store the first occurrence of each prefix sum. For each index i, we find the prefix sum till index i, say prefSum and find the first occurrence of (prefSum - (total sum - k)) in the hash map, if present. The difference between the first occurrence and the current index i will be the length of the subarray.

To know more about the algorithm, please refer Longest Subarray Having Sum K.

C++
// C++ code for Minimum removal for target sum using Prefix array

#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;

int minRemovals(vector<int> &arr, int k) {
    int total = 0;
    for (int num : arr)
        total += num;
  
    if(k == total)
        return arr.size();
  
    // Find the target sum for the longest subarray
    int target = total - k;
    unordered_map<int, int> prefIdx;

    int prefSum = 0, maxLen = -1;
    for (int i = 0; i < arr.size(); i++) {
        prefSum += arr[i];
        
        if(prefSum == target)
            maxLen = i + 1;
        else if (prefIdx.find(prefSum - target) != prefIdx.end())
            maxLen = max(maxLen, i - prefIdx[prefSum - target]);
        
        // Store prefix sum with its index
        if(prefIdx.find(prefSum) == prefIdx.end())
            prefIdx[prefSum] = i;
    }
    return maxLen == -1 ? -1 : arr.size() - maxLen;
}

int main() {
    vector<int> arr = {3, 4, 1, 3, 2};
    int k = 5;
    cout << minRemovals(arr, k) << endl;
    return 0;
}
Java
// Java code for Minimum removal for target sum using Prefix array

import java.util.*;

class GfG {
    static int minRemovals(int[] arr, int k) {
        int total = 0;
        for (int num : arr)
            total += num;

        if (k == total)
            return arr.length;

        // Find the target sum for the longest subarray
        int target = total - k;
        Map<Integer, Integer> prefIdx = new HashMap<>();

        int prefSum = 0, maxLen = -1;
        for (int i = 0; i < arr.length; i++) {
            prefSum += arr[i];

            if (prefSum == target)
                maxLen = i + 1;
            else if (prefIdx.containsKey(prefSum - target))
                maxLen = Math.max(maxLen, i - prefIdx.get(prefSum - target));

            // Store prefix sum with its index
            if (!prefIdx.containsKey(prefSum))
                prefIdx.put(prefSum, i);
        }
        return maxLen == -1 ? -1 : arr.length - maxLen;
    }

    public static void main(String[] args) {
        int[] arr = {3, 4, 1, 3, 2};
        int k = 5;
        System.out.println(minRemovals(arr, k));
    }
}
Python
# Python code for Minimum removal for target sum using Prefix array

def minRemovals(arr, k):
    total = 0
    for num in arr:
        total += num

    if k == total:
        return len(arr)

    # Find the target sum for the longest subarray
    target = total - k
    prefIdx = {}

    prefSum = 0
    maxLen = -1
    for i in range(len(arr)):
        prefSum += arr[i]

        if prefSum == target:
            maxLen = i + 1
        elif (prefSum - target) in prefIdx:
            maxLen = max(maxLen, i - prefIdx[prefSum - target])

        # Store prefix sum with its index
        if prefSum not in prefIdx:
            prefIdx[prefSum] = i

    return -1 if maxLen == -1 else len(arr) - maxLen


if __name__ == "__main__":
    arr = [3, 4, 1, 3, 2]
    k = 5
    print(minRemovals(arr, k))
C#
// C# code for Minimum removal for target sum using Prefix array

using System;
using System.Collections.Generic;

class GfG {
    static int MinRemovals(int[] arr, int k) {
        int total = 0;
        foreach (int num in arr)
            total += num;

        if (k == total)
            return arr.Length;

        // Find the target sum for the longest subarray
        int target = total - k;
        Dictionary<int, int> prefIdx = new Dictionary<int, int>();

        int prefSum = 0, maxLen = -1;
        for (int i = 0; i < arr.Length; i++) {
            prefSum += arr[i];

            if (prefSum == target)
                maxLen = i + 1;
            else if (prefIdx.ContainsKey(prefSum - target))
                maxLen = Math.Max(maxLen, i - prefIdx[prefSum - target]);

            // Store prefix sum with its index
            if (!prefIdx.ContainsKey(prefSum))
                prefIdx[prefSum] = i;
        }
        return maxLen == -1 ? -1 : arr.Length - maxLen;
    }

    static void Main() {
        int[] arr = { 3, 4, 1, 3, 2 };
        int k = 5;
        Console.WriteLine(MinRemovals(arr, k));
    }
}
JavaScript
// JavaScript code for Minimum removal for target sum using
// Prefix array

function minRemovals(arr, k) {
    let total = 0;
    for (let num of arr)
        total += num;

    if (k === total)
        return arr.length;

    // Find the target sum for the longest subarray
    let target = total - k;
    let prefIdx = new Map();

    let prefSum = 0, maxLen = -1;
    for (let i = 0; i < arr.length; i++) {
        prefSum += arr[i];

        if (prefSum === target)
            maxLen = i + 1;
        else if (prefIdx.has(prefSum - target))
            maxLen = Math.max(maxLen, i - prefIdx.get(prefSum - target));

        // Store prefix sum with its index
        if (!prefIdx.has(prefSum))
            prefIdx.set(prefSum, i);
    }

    return maxLen === -1 ? -1 : arr.length - maxLen;
}

// Driver Code
const arr = [3, 4, 1, 3, 2];
const k = 5;
console.log(minRemovals(arr, k));

Output
2

[Expected Approach] Using Sliding Window Technique - O(n) Time and O(1) Space

In the previous approach, we observed that in order to find the minimum removals with sum k, we need to find the longest subarray with sum (total sum - k). Since the input array contains only positive numbers, we can further optimize our previous approach by using Sliding Window Technique to find the longest subarray having sum = (total sum - k).

  • Start with a window of size 1 having only the first element.
  • Extend the window until the sum of elements exceeds (total sum - k).
  • Shrink the window from the left until sum of elements <= (total sum - k).
  • If sum of elements == (total sum - k), find the length of window (right - left + 1) and update the maximum length.

Finally, minimum removals = n - maximum length of window having sum as (total sum - k).

    C++
    // C++ code for Minimum removal for target sum using
    // Two pointers
    
    #include <climits>
    #include <iostream>
    #include <vector>
    using namespace std;
    
    int minRemovals(vector<int> &arr, int k) {
        int total = 0, n = arr.size();
        for (int num : arr)
            total += num;
    
        int target = total - k;
    
        // If target sum = 0, all elements must be removed
        if (target == 0)
            return n;
    
        int left = 0, currSum = 0, maxLen = -1;
    
        // Use the sliding window technique
        for (int right = 0; right < n; right++) {
            currSum += arr[right];
    
            // Shrink the window from the left if the
            // current sum exceeds the required sum
            while (left < right && currSum > target) {
                currSum -= arr[left++];
            }
    
            if (currSum == target) {
                maxLen = max(maxLen, right - left + 1);
            }
        }
    
        // If no valid subarray is found, return -1;
        // otherwise, return the minimum removals
        return maxLen == -1 ? -1 : n - maxLen;
    }
    
    int main() {
        vector<int> arr = {3, 4, 1, 3, 2};
        int k = 5;
        cout << minRemovals(arr, k) << endl;
        return 0;
    }
    
    Java
    // Java code for Minimum removal for target sum using
    // Two pointers
    
    import java.util.*;
    
    class GfG {
        static int minRemovals(int[] arr, int k) {
            int total = 0, n = arr.length;
            for (int num : arr)
                total += num;
    
            int target = total - k;
    
            // If target sum = 0, all elements must be removed
            if (target == 0)
                return n;
    
            int left = 0, currSum = 0, maxLen = -1;
    
            // Use the sliding window technique
            for (int right = 0; right < n; right++) {
                currSum += arr[right];
    
                // Shrink the window from the left if the
                // current sum exceeds the required sum
                while (left < right && currSum > target) {
                    currSum -= arr[left++];
                }
    
                if (currSum == target) {
                    maxLen = Math.max(maxLen, right - left + 1);
                }
            }
    
            // If no valid subarray is found, return -1;
            // otherwise, return the minimum removals
            return maxLen == -1 ? -1 : n - maxLen;
        }
    
        public static void main(String[] args) {
            int[] arr = {3, 4, 1, 3, 2};
            int k = 5;
            System.out.println(minRemovals(arr, k));
        }
    }
    
    Python
    # Python code for Minimum removal for target sum using Two pointers
    
    def minRemovals(arr, k):
        total = 0
        n = len(arr)
        
        for num in arr:
            total += num
    
        target = total - k
    
        # If target sum = 0, all elements must be removed
        if target == 0:
            return n
    
        left = 0
        currSum = 0
        maxLen = -1
    
        # Use the sliding window technique
        for right in range(n):
            currSum += arr[right]
    
            # Shrink the window from the left if the
            # current sum exceeds the required sum
            while left < right and currSum > target:
                currSum -= arr[left]
                left += 1
    
            if currSum == target:
                maxLen = max(maxLen, right - left + 1)
    
        # If no valid subarray is found, return -1;
        # otherwise, return the minimum removals
        return -1 if maxLen == -1 else n - maxLen
    
    
    if __name__ == "__main__":
        arr = [3, 4, 1, 3, 2]
        k = 5
        print(minRemovals(arr, k))
    
    C#
    // C# code for Minimum removal for target sum using
    // Two pointers
    
    using System;
    class GfG {
        static int minRemovals(int[] arr, int k) {
            int total = 0, n = arr.Length;
            
            foreach (int num in arr)
                total += num;
    
            int target = total - k;
    
            // If target sum = 0, all elements must be removed
            if (target == 0)
                return n;
    
            int left = 0, currSum = 0, maxLen = -1;
    
            // Use the sliding window technique
            for (int right = 0; right < n; right++) {
                currSum += arr[right];
    
                // Shrink the window from the left if the
                // current sum exceeds the required sum
                while (left < right && currSum > target) {
                    currSum -= arr[left++];
                }
    
                if (currSum == target) {
                    maxLen = Math.Max(maxLen, right - left + 1);
                }
            }
    
            // If no valid subarray is found, return -1;
            // otherwise, return the minimum removals
            return maxLen == -1 ? -1 : n - maxLen;
        }
    
        static void Main() {
            int[] arr = new int[] { 3, 4, 1, 3, 2 };
            int k = 5;
            Console.WriteLine(minRemovals(arr, k));
        }
    }
    
    JavaScript
    // JavaScript code for Minimum removal for target sum using
    // Two pointers
    
    function minRemovals(arr, k) {
        let total = 0, n = arr.length;
        
        for (let num of arr) {
            total += num;
        }
    
        let target = total - k;
    
        // If target sum = 0, all elements must be removed
        if (target === 0) {
            return n;
        }
    
        let left = 0, currSum = 0, maxLen = -1;
    
        // Use the sliding window technique
        for (let right = 0; right < n; right++) {
            currSum += arr[right];
    
            // Shrink the window from the left if the
            // current sum exceeds the required sum
            while (left < right && currSum > target) {
                currSum -= arr[left++];
            }
    
            if (currSum === target) {
                maxLen = Math.max(maxLen, right - left + 1);
            }
        }
    
        // If no valid subarray is found, return -1;
        // otherwise, return the minimum removals
        return maxLen === -1 ? -1 : n - maxLen;
    }
    
    // Driver Code
    const arr = [3, 4, 1, 3, 2];
    const k = 5;
    console.log(minRemovals(arr, k));
    

    Output
    2
    

    Minimum Removals for Target Sum
    Visit Course explore course icon
    Article Tags :
    Practice Tags :

    Similar Reads