Open in App
Not now

# Maximum possible difference between two Subarrays after removing N elements from Array

• Last Updated : 21 Mar, 2023

Given an array arr[] which is of 3*N size, the task is to remove N elements and divide the whole array into two equal parts such that the  difference of the sum of the left subarray and right subarray should yield to maximum.

Examples:

Input: arr[] = [5, 4, 4, 2, 3, 3]
Output: 4
Explanation:  The ‘2’ elements to be removed are [4, 3].
and when you divide the array into two equal parts after the removal
left subarray= [5, 4], right subarray= [2, 3].
The Sum difference between them is (9-5) = 4

Input: arr[] = [4, 5, 6, 1, 2, 8, 7, 9, 3]
Output: 9

Approach:

Split the array into two subarrays at some point i (N <= i <= 2 * N). We remove i – N smallest elements from the first subarray, and (2 * N – i) largest elements from the second subarray. That way, for a given split, we get the largest possible sum_first, and smallest possible sum_second.

Using Max and Min heap to keep track of the smallest and largest elements, respectively. And update the difference.

Follow the below steps to Implement the Idea:

• Initialize a final_diff variable to store the maximum difference between left and right subarray after removal of N elements.
• Run a for loop from N to 2*N and arr[] into two halves left and right.
• Remove i – N smallest elements from left array and 2*N – i largest elements from right array by using Min and Max heap.
• Calculate the sum of N largest values in left array and N smallest values in right array and find out the difference between them and store it in Curr_diff variable.
• Maximize the value of final_diff with curr_diff
• Return the value of final_diff.

Below is the implementation

## C++

 `#include ` `#include ` `#include ` `#include ` `#include ` `#include `   `using` `namespace` `std;`   `// This function returns the (1, n-1) min and max` `// elements which are to be discarded from the array` `vector<``int``> best_remove(vector<``int``> left, vector<``int``> right, ``int` `n) {` `  ``vector<``int``> temp;` `  ``priority_queue<``int``, vector<``int``>, greater<``int``>> leftHeap(left.begin(), left.end());` `  ``priority_queue<``int``, vector<``int``>, less<``int``>> rightHeap(right.begin(), right.end());`   `  ``if` `(left.size() == n && right.size() > n) ` `  ``{` `    ``// remove all n elements from the right side` `    ``int` `count = 0;` `    ``while` `(count < n) {` `      ``temp.push_back(rightHeap.top());` `      ``rightHeap.pop();` `      ``count++;` `    ``}` `  ``} ``else` `if` `(right.size() == n && left.size() > n)` `  ``{` `    ``// remove all element from the left side` `    ``int` `count = 0;` `    ``while` `(count < n) {` `      ``temp.push_back(leftHeap.top());` `      ``leftHeap.pop();` `      ``count++;` `    ``}` `  ``} ``else` `{` `    ``int` `x = left.size() - n;` `    ``int` `count = 0;` `    ``while` `(count < n - x) {` `      ``temp.push_back(leftHeap.top());` `      ``leftHeap.pop();` `      ``count++;` `    ``}` `    ``count = 0;` `    ``while` `(count < x) {` `      ``temp.push_back(rightHeap.top());` `      ``rightHeap.pop();` `      ``count++;` `    ``}` `  ``}` `  ``return` `temp;` `}`   `vector<``int``> remove_elements(vector<``int``> parent, vector<``int``> child) {` `  ``vector<``int``> result;` `  ``unordered_map<``int``, ``int``> childCount;` `  ``for` `(``int` `i : child) {` `    ``int` `count = childCount[i];` `    ``childCount[i] = count + 1;` `  ``}`   `  ``for` `(``int` `i : parent) {` `    ``if` `(childCount[i] > 0) {` `      ``childCount[i]--;` `    ``} ``else` `{` `      ``result.push_back(i);` `    ``}` `  ``}` `  ``return` `result;` `}`   `int` `max_diff(vector<``int``> arr, ``int` `n) {` `  ``int` `mid = arr.size() / 2;`   `  ``int` `left = accumulate(arr.begin(), arr.begin() + mid, 0);` `  ``int` `right = accumulate(arr.begin() + mid, arr.end(), 0);`   `  ``return` `left - right + 1;` `}`   `int` `main() {` `  ``vector<``int``> arr = {7, 9, 5, 8, 1, 3};` `  ``int` `n = arr.size() / 3;`   `  ``int` `final_max = INT_MIN;`   `  ``// starting from the index 2` `  ``for` `(``int` `i = n; i <= 2 * n; i++) {` `    ``vector<``int``> left(arr.begin(), arr.begin() + i); ``// dividing the left` `    ``vector<``int``> right(arr.begin() + i, arr.end()); ``// dividing the right sub array` `    ``vector<``int``> bestRemoveElements = best_remove(left, right, n);` `    ``vector<``int``> dup = arr;` `    ``vector<``int``> removeElements = remove_elements(dup, bestRemoveElements);` `    ``int` `currMax = max_diff(removeElements, n);` `    ``final_max = max(final_max, currMax)-1;` `  ``}`   `  ``cout << ``"The maximum difference between S1 and S2 is "` `<< final_max << endl;` `  ``return` `0;` `}`

## Java

 `import` `java.util.*;` `import` `java.util.stream.Collectors;`   `public` `class` `Main {`   `    ``// This function returns the (1, n-1) min and max` `    ``// elements which are to be discarded from the array` `    ``static` `List best_remove(List left, List right, ``int` `n) {` `        ``List temp = ``new` `ArrayList<>();` `        ``PriorityQueue leftHeap = ``new` `PriorityQueue<>(left);` `        ``PriorityQueue rightHeap = ``new` `PriorityQueue<>(right);`   `        ``if` `(left.size() == n && right.size() > n) ` `        ``{` `          `  `            ``// remove all n elements from the right side` `            ``temp.addAll(rightHeap.stream().sorted(Collections.reverseOrder()).limit(n).collect(Collectors.toList()));` `        ``} ``else` `if` `(right.size() == n && left.size() > n)` `        ``{` `          `  `            ``// remove all element from the left side` `            ``temp.addAll(leftHeap.stream().limit(n).collect(Collectors.toList()));` `        ``} ``else` `{` `            ``int` `x = left.size() - n;` `            ``temp.addAll(leftHeap.stream().limit(n - x).collect(Collectors.toList()));` `            ``temp.addAll(rightHeap.stream().sorted(Collections.reverseOrder()).limit(x).collect(Collectors.toList()));` `        ``}` `        ``return` `temp;` `    ``}`   `    ``static` `List remove_elements(List parent, List child) {` `        ``List result = ``new` `ArrayList<>();` `        ``Map childCount = ``new` `HashMap<>();` `        ``for` `(Integer i : child) {` `            ``int` `count = childCount.getOrDefault(i, ``0``);` `            ``childCount.put(i, count + ``1``);` `        ``}`   `        ``for` `(Integer i : parent) {` `            ``if` `(childCount.containsKey(i) && childCount.get(i) > ``0``) {` `                ``childCount.put(i, childCount.get(i) - ``1``);` `            ``} ``else` `{` `                ``result.add(i);` `            ``}` `        ``}` `        ``return` `result;` `    ``}`   `    ``static` `int` `max_diff(List arr, ``int` `n) {` `        ``int` `mid = arr.size() / ``2``;`   `        ``int` `left = arr.subList(``0``, mid).stream().mapToInt(Integer::intValue).sum();` `        ``int` `right = arr.subList(mid, arr.size()).stream().mapToInt(Integer::intValue).sum();`   `        ``return` `left - right + ``1``;` `    ``}`   `    ``public` `static` `void` `main(String[] args) {` `        ``List arr = Arrays.asList(``7``, ``9``, ``5``, ``8``, ``1``, ``3``);` `        ``int` `n = arr.size() / ``3``;`   `        ``int` `final_max = Integer.MIN_VALUE;`   `        ``// starting from the index 2` `        ``for` `(``int` `i = n; i <= ``2` `* n; i++) {` `            ``List left = arr.subList(``0``, i); ``// dividing the left` `            ``List right = arr.subList(i, arr.size()); ``// dividing the right sub array` `            ``List bestRemoveElements = best_remove(left, right, n);` `            ``List dup = ``new` `ArrayList<>(arr);` `            ``List removeElements = remove_elements(dup, bestRemoveElements);` `            ``int` `currMax = max_diff(removeElements, n);` `            ``final_max = Math.max(final_max, currMax);` `        ``}`   `        ``System.out.println(``"The maximum difference between S1 and S2 is "` `+ final_max);` `    ``}` `}`

## Python3

 `import` `copy` `import` `heapq` `from` `collections ``import` `Counter`     `# This function return the (1, n-1) min and max ` `# elements which are t be discarded from the array` `def` `best_remove(left, right):`   `    ``temp ``=` `[]` `    ``heapq.heapify(left)` `    ``heapq.heapify(right)`   `    ``if` `len``(left) ``=``=` `n ``and` `len``(right) > n:` `        ``# remove all n elements from the right side` `        ``temp.extend(heapq.nlargest(n, right))` `    ``elif` `len``(right) ``=``=` `n ``and` `len``(left) > n:` `        ``# remove all element from the left side` `        ``temp.extend(heapq.nsmallest(n, left))` `    ``else``:` `        ``x ``=` `len``(left) ``-` `n` `        ``temp.extend(heapq.nsmallest(x, left)``+``heapq.nlargest(n``-``x, right))` `    ``return` `temp`     `def` `remove_elements(parent, child):`   `    ``f_s ``=` `Counter(child)` `    `  `    ``# storing all the elements of right` `    ``# part to preserve the order incase of duplicates` `    ``r_h ``=` `[]  `   `    ``for` `i ``in` `parent:` `        ``if` `i ``in` `f_s ``and` `f_s[i] > ``0``:` `            ``f_s[i] ``-``=` `1` `        ``else``:` `            ``r_h.append(i)`   `    ``# print("after r", left + r_h)` `    ``return` `r_h`   `    ``# Remove the child from parent` `    ``# divide the array` `    ``# sum the left and right elements` `    ``# track the curr max sum until the for loops terminates` `    ``# return the final max difference` `    ``# print(parent, n, child, m)`   `    ``# print(left, right)`     `def` `max_diff(arr):  ``# function that calculate the sum of maximum difference between two arrays` `    ``# print(arr)`   `    ``mid ``=` `len``(arr)``/``/``2`   `    ``left ``=` `sum``(arr[:mid])` `    ``right ``=` `sum``(arr[mid:])` `    ``return` `left``-``right`     `arr ``=` `[``7``, ``9``, ``5``, ``8``, ``1``, ``3``]` `n ``=` `len``(arr)``/``/``3`   `final_max ``=` `-``float``(``"inf"``)`   `# starting from the index 2` `for` `i ``in` `range``(n, ``2` `*` `n ``+` `1``):`   `    ``left ``=` `arr[:i]  ``# dividing the left` `    ``right ``=` `arr[i:]  ``# dividing the right sub array`   `    ``# print(left, right)`   `    ``# functions which returns the best elements to be removed from both sub arrays` `    ``best_remove_elements ``=` `best_remove(left, right)` `    ``# print(best_remove_elements)`   `    ``dup ``=` `[]` `    ``# copying the original array so that the changes might not reflect` `    ``dup ``=` `copy.deepcopy(arr)`   `    ``# function that returns the array after removing the best_remove elements` `    ``remove_element ``=` `remove_elements(dup, best_remove_elements)` `    ``# print(remove_element)` `    ``# return(remove_element)`   `    ``curr_max ``=` `max_diff(remove_element)  ``# tracking the maximum` `    ``final_max ``=` `max``(final_max, curr_max)`   `print``(``"The maximum difference between S1 and S2 is"``, final_max)`

## C#

 `using` `System;` `using` `System.Linq;` `using` `System.Collections.Generic;`   `public` `class` `GFG {`     `// This function return the (1, n-1) min and max ` `// elements which are t be discarded from the array` `static` `List<``int``> BestRemove(List<``int``> left, List<``int``> right, ``int` `n)` `{` `    ``List<``int``> temp = ``new` `List<``int``>();` `    ``left.Sort();` `    ``right.Sort();` `    `  `    ``if` `(left.Count == n && right.Count > n)` `    `  `        ``// remove all n elements from the right side` `        ``temp.AddRange(right.OrderByDescending(x => x).Take(n));` `        `  `    ``else` `if` `(right.Count == n && left.Count > n)` `    `  `        ``// remove all element from the left side` `        ``temp.AddRange(left.OrderBy(x => x).Take(n));` `    ``else` `{` `        ``int` `x = left.Count - n;` `        ``temp.AddRange(left.OrderBy(x => x).Take(x));` `        ``temp.AddRange(right.OrderByDescending(x => x).Take(n - x));` `    ``}` `    `  `    ``return` `temp;` `}`   `static` `List<``int``> RemoveElements(List<``int``> parent, List<``int``> child)` `{` `    ``Dictionary<``int``, ``int``> f_s = child.GroupBy(x => x).ToDictionary(g => g.Key, g => g.Count());` `    `  `    `  `    ``// storing all the elements of right` `    ``// part to preserve the order incase of duplicates` `    ``List<``int``> r_h = ``new` `List<``int``>();` `    `  `    ``foreach` `(``int` `i ``in` `parent) {` `        ``if` `(f_s.ContainsKey(i) && f_s[i] > 0)` `            ``f_s[i] -= 1;` `        ``else` `            ``r_h.Add(i);` `    ``}` `    `  `    ``// print("after r", left + r_h)` `    ``return` `r_h;` `}`     `// Remove the child from parent` `// divide the array` `// sum the left and right elements` `// track the curr max sum until the for loops terminates` `// return the final max difference` `// print(parent, n, child, m)` `// print(left, right)`     `// function that calculate the sum of maximum difference between two arrays` `// print(arr)` `static` `int` `GetMaxDiff(List<``int``> arr, ``int` `n)` `{` `    ``int` `mid = arr.Count / 2;` `    ``List<``int``> left = arr.Take(mid).ToList();` `    ``List<``int``> right = arr.Skip(mid).ToList();` `    ``int` `diff = left.Sum() - right.Sum();` `    ``return` `diff;` `}`   `public` `static` `void` `Main()` `{` `    ``int``[] arr = {7, 9, 5, 8, 1, 3};` `    ``int` `n = arr.Length / 3;` `    ``int` `finalMax = ``int``.MinValue;` `    `  `    `  `    ``// starting from the index 2` `    ``for` `(``int` `i = n; i <= 2 * n; i++) {` `        `  `        ``// functions which returns the best elements to be removed from both sub arrays` `        ``List<``int``> bestRemoveElements = BestRemove(arr.Take(i).ToList(), arr.Skip(i).ToList(), n);` `        `  `        ``// copying the original array so that the changes might not reflect` `        ``List<``int``> dup = ``new` `List<``int``>(arr);` `        `  `        ``// function that returns the array after removing the best_remove elements` `        ``List<``int``> removeElements = RemoveElements(dup, bestRemoveElements);` `        ``int` `currMax = GetMaxDiff(removeElements, n); ``// tracking the maximum` `        ``finalMax = Math.Max(finalMax, currMax);` `    ``}` `    `  `    ``Console.WriteLine(``"The maximum difference between S1 and S2 is {0}"``, finalMax);` `}` `}`   `// This code is contributed by Shivhack999`

## Javascript

 `function` `best_remove(left, right, n) {` `    ``let temp = [];` `    ``left.sort();` `    ``right.sort();`   `    ``if` `(left.length == n && right.length > n) {` `        ``temp.push(...right.sort((a, b) => b - a).slice(0, n));` `    ``} ``else` `if` `(right.length == n && left.length > n) {` `        ``temp.push(...left.sort((a, b) => a - b).slice(0, n));` `    ``} ``else` `{` `        ``let x = left.length - n;` `        ``temp.push(...left.sort((a, b) => a - b).slice(0, x));` `        ``temp.push(...right.sort((a, b) => b - a).slice(0, n - x));` `    ``}`   `    ``return` `temp;` `}`   `function` `remove_elements(parent, child) {` `    ``let f_s = child.reduce((acc, val) => {` `        ``acc[val] = (acc[val] || 0) + 1;` `        ``return` `acc;` `    ``}, {});`   `    ``let r_h = [];` `    ``for` `(let i = 0; i < parent.length; i++) {` `        ``if` `(f_s[parent[i]] && f_s[parent[i]] > 0) {` `            ``f_s[parent[i]]--;` `        ``} ``else` `{` `            ``r_h.push(parent[i]);` `        ``}` `    ``}`   `    ``return` `r_h;` `}`   `function` `max_diff(arr, n) {` `    ``let mid = Math.floor(arr.length / 2);` `    ``let left = arr.slice(0, mid);` `    ``let right = arr.slice(mid);` `    ``let diff = left.reduce((acc, val) => acc + val, 0) - right.reduce((acc, val) => acc + val, 0);` `    ``return` `diff;` `}`   `let arr = [7, 9, 5, 8, 1, 3];` `let n = Math.floor(arr.length / 3);` `let finalMax = Number.MIN_SAFE_INTEGER;`   `for` `(let i = n; i <= 2 * n; i++) {` `    ``let bestRemoveElements = best_remove(arr.slice(0, i), arr.slice(i), n);` `    ``let dup = [...arr];` `    ``let removeElement = remove_elements(dup, bestRemoveElements);` `    ``let currMax = max_diff(removeElement, n);` `    ``finalMax = Math.max(finalMax, currMax);` `}`   `console.log(``"The maximum difference between S1 and S2 is "` `+ finalMax);`

Output

`The maximum difference between S1 and S2 is 13`

Time Complexity: (N*log(N))
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up
Related Articles