Minimum Removals for Target Sum

Last Updated : 4 Aug, 2025

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. 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.

Try It Yourself
redirect icon

[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++
#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
#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
class GfG {

    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
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#
using System;
class GfG {
  
    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
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++
#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
import java.util.Map;
import java.util.HashMap;

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
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#
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
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++
#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
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
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#
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
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
Comment