Partitioning into two contiguous element subarrays with equal sums
Given an array of n positive integers. Find a minimum positive element to be added to one of the indexes in the array such that it can be partitioned into two contiguous sub-arrays of equal sums. Output the minimum element to be added and the position where it is to be added. If multiple positions are possible then return the least one.
Examples:
Input : arr[] = { 10, 1, 2, 3, 4 }
Output : 0 0
Explanation: The array can already be partitioned into two contiguous subarrays i.e. {10} and {1, 2, 3, 4} with equal sums. So we need to add 0 at any position. (least position is 0)
Input : arr[] = { 5, 4 }
Output : 1 1
Explanation: We need to add 1 to 4 so that two sub arrays are {5},{5} hence output is 1 1 (minimum element and it’s position where it is to be added.
Prerequisites: Prefix Sums
Method 1 (Simple): A naive approach is to calculate the sum of elements from (arr[0] to arr[i]) and (arr[i+1] to arr[n-1]), and at each step find the difference between these two sums, minimum difference will give the element to be added.
Method 2 (Efficient): Careful analysis suggests that we can use the concept of prefix sums and suffix sums. Calculate both of them and find the absolute difference between prefixSum[i] (where prefixSum[i] is the sum of array elements upto ith position) and suffixSum[i + 1] (where suffixSum[i + 1] is the sum of array elements from (i + 1)th position to last position).
For e.g.
arr 10 1 2 3 4
prefixSum 10 11 13 16 20
suffixSum 20 10 9 7 4
Absolute difference between suffixSum[i + 1] and prefixSum[i]
10 - 10 = 0 // minimum
11 - 9 = 1
13 - 7 = 6
16 - 4 = 12
Thus, minimum element is 0, for position,
if prefixSum[i] is greater than suffixSum[i + 1], then position is "i + 1".
else it's is "i".
Below is the implementation of above approach.
C++
#include <bits/stdc++.h>
using namespace std;
struct data {
int element;
int position;
};
struct data findMinElement( int arr[], int n)
{
struct data result;
int prefixSum[n] = { 0 };
int suffixSum[n] = { 0 };
prefixSum[0] = arr[0];
for ( int i = 1; i < n; i++) {
prefixSum[i] = prefixSum[i - 1] + arr[i];
}
suffixSum[n - 1] = arr[n - 1];
for ( int i = n - 2; i >= 0; i--) {
suffixSum[i] = suffixSum[i + 1] + arr[i];
}
int min = suffixSum[0];
int pos;
for ( int i = 0; i < n - 1; i++) {
if ( abs (suffixSum[i + 1] - prefixSum[i]) < min) {
min = abs (suffixSum[i + 1] - prefixSum[i]);
if (suffixSum[i + 1] < prefixSum[i]) pos = i + 1;
else pos = i;
}
}
result.element = min;
result.position = pos;
return result;
}
int main()
{
int arr[] = { 10, 1, 2, 3, 4 };
int n = sizeof (arr) / sizeof (arr[0]);
struct data values;
values = findMinElement(arr, n);
cout << "Minimum element : " << values.element
<< endl << "Position : " << values.position;
return 0;
}
|
Java
import java.util.*;
class GFG
{
static class data
{
int element;
int position;
};
static data findMinElement( int arr[], int n)
{
data result= new data();
int []prefixSum = new int [n];
int []suffixSum = new int [n];
prefixSum[ 0 ] = arr[ 0 ];
for ( int i = 1 ; i < n; i++)
{
prefixSum[i] = prefixSum[i - 1 ] + arr[i];
}
suffixSum[n - 1 ] = arr[n - 1 ];
for ( int i = n - 2 ; i >= 0 ; i--)
{
suffixSum[i] = suffixSum[i + 1 ] + arr[i];
}
int min = suffixSum[ 0 ];
int pos= 0 ;
for ( int i = 0 ; i < n - 1 ; i++)
{
if (Math.abs(suffixSum[i + 1 ] - prefixSum[i]) < min)
{
min = Math.abs(suffixSum[i + 1 ] - prefixSum[i]);
if (suffixSum[i + 1 ] < prefixSum[i]) pos = i + 1 ;
else pos = i;
}
}
result.element = min;
result.position = pos;
return result;
}
public static void main(String[] args)
{
int arr[] = { 10 , 1 , 2 , 3 , 4 };
int n = arr.length;
data values;
values = findMinElement(arr, n);
System.out.println( "Minimum element : " + values.element
+ "\nPosition : " + values.position);
}
}
|
Python3
class Data:
def __init__( self ):
self .element = - 1
self .position = - 1
def findMinElement(arr, n):
result = Data()
prefixSum = [ 0 ] * n
suffixSum = [ 0 ] * n
prefixSum[ 0 ] = arr[ 0 ]
for i in range ( 1 , n):
prefixSum[i] = prefixSum[i - 1 ] + arr[i]\
suffixSum[n - 1 ] = arr[n - 1 ]
for i in range (n - 2 , - 1 , - 1 ):
suffixSum[i] = suffixSum[i + 1 ] + arr[i]
mini = suffixSum[ 0 ]
pos = 0
for i in range (n - 1 ):
if abs (suffixSum[i + 1 ] - prefixSum[i]) < mini:
mini = abs (suffixSum[i + 1 ] - prefixSum[i])
if suffixSum[i + 1 ] < prefixSum[i]:
pos = i + 1
else :
pos = i
result.element = mini
result.position = pos
return result
if __name__ = = "__main__" :
arr = [ 10 , 1 , 2 , 3 , 4 ]
n = len (arr)
values = Data()
values = findMinElement(arr, n)
print ( "Minimum element :" , values.element, "\nPosition :" , values.position)
|
C#
using System;
class GFG
{
public class data
{
public int element;
public int position;
};
static data findMinElement( int []arr, int n)
{
data result = new data();
int []prefixSum = new int [n];
int []suffixSum = new int [n];
prefixSum[0] = arr[0];
for ( int i = 1; i < n; i++)
{
prefixSum[i] = prefixSum[i - 1] + arr[i];
}
suffixSum[n - 1] = arr[n - 1];
for ( int i = n - 2; i >= 0; i--)
{
suffixSum[i] = suffixSum[i + 1] + arr[i];
}
int min = suffixSum[0];
int pos = 0;
for ( int i = 0; i < n - 1; i++)
{
if (Math.Abs(suffixSum[i + 1] -
prefixSum[i]) < min)
{
min = Math.Abs(suffixSum[i + 1] -
prefixSum[i]);
if (suffixSum[i + 1] < prefixSum[i])
pos = i + 1;
else
pos = i;
}
}
result.element = min;
result.position = pos;
return result;
}
public static void Main(String[] args)
{
int []arr = { 10, 1, 2, 3, 4 };
int n = arr.Length;
data values;
values = findMinElement(arr, n);
Console.WriteLine( "Minimum element : " +
values.element +
"\nPosition : " +
values.position);
}
}
|
Javascript
<script>
class data
{
constructor(element, position){
this .element = element;
this .position = position;
}
};
function findMinElement(arr, n)
{
let result = new data();
let prefixSum = new Array(n);
let suffixSum = new Array(n);
prefixSum[0] = arr[0];
for (let i = 1; i < n; i++)
{
prefixSum[i] = prefixSum[i - 1] + arr[i];
}
suffixSum[n - 1] = arr[n - 1];
for (let i = n - 2; i >= 0; i--)
{
suffixSum[i] = suffixSum[i + 1] + arr[i];
}
let min = suffixSum[0];
let pos=0;
for (let i = 0; i < n - 1; i++)
{
if (Math.abs(suffixSum[i + 1] - prefixSum[i]) < min)
{
min = Math.abs(suffixSum[i + 1] - prefixSum[i]);
if (suffixSum[i + 1] < prefixSum[i]) pos = i + 1;
else pos = i;
}
}
result.element = min;
result.position = pos;
return result;
}
let arr = [ 10, 1, 2, 3, 4 ];
let n = arr.length;
let values;
values = findMinElement(arr, n);
document.write( "Minimum element : " +
values.element + "<br>Position : " + values.position);
</script>
|
Output
Minimum element : 0
Position : 0
Complexity Analysis:
- Time Complexity: O(n)
- Auxiliary Space: O(n)
Last Updated :
17 Aug, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...