Given an integer K and an array A[] of size N, the task is to create a new array with sum K with minimum number of operations, where in each operation, an element can be removed either from the start or end of A[] and appended to the new array. If it is not possible to generate a new array with sum K, print -1. If there are multiple answers, print any one of them.
Examples
Input: K = 6, A[] = {1, 2, 3, 1, 3}, N = 5
Output: 1 3 2
Explanation: Operation 1: Removing A[0] modifies A[] to {2, 3, 1, 3}. Sum = 1.
Operation 2: Removing A[3] modifies A[] to {2, 1, 3}. Sum = 4.
Operation 3: Removing A[0] modifies A[] to {1, 3}. Sum = 6.
Input: K = 5, A[] = {1, 2, 7}, N = 3
Output: -1
Naive Approach: Follow the steps below to solve the problem:
- The task is to find two minimum length subarrays, one from the beginning and one from the end of the array (possibly empty), such that their sum is equal to K.
- Traverse the array from the left and calculate the subarray needed to be removed from the right such that the total sum is K.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minSizeArr( int A[], int N, int K)
{
int leftTaken = N, rightTaken = N;
int leftSum = 0, rightSum = 0;
for ( int left = -1; left < N; left++) {
if (left != -1)
leftSum += A[left];
rightSum = 0;
for ( int right = N - 1; right > left; right--) {
rightSum += A[right];
if (leftSum + rightSum == K) {
if (leftTaken + rightTaken
> (left + 1) + (N - right)) {
leftTaken = left + 1;
rightTaken = N - right;
}
break ;
}
if (leftSum + rightSum > K)
break ;
}
}
if (leftTaken + rightTaken <= N) {
for ( int i = 0; i < leftTaken; i++)
cout << A[i] << " " ;
for ( int i = 0; i < rightTaken; i++)
cout << A[N - i - 1] << " " ;
}
else
cout << -1;
}
int main()
{
int N = 7;
int A[] = { 3, 2, 1, 1, 1, 1, 3 };
int K = 10;
minSizeArr(A, N, K);
return 0;
}
|
Java
import java.util.*;
class GFG{
static void minSizeArr( int A[], int N, int K)
{
int leftTaken = N, rightTaken = N;
int leftSum = 0 , rightSum = 0 ;
for ( int left = - 1 ; left < N; left++) {
if (left != - 1 )
leftSum += A[left];
rightSum = 0 ;
for ( int right = N - 1 ; right > left; right--)
{
rightSum += A[right];
if (leftSum + rightSum == K) {
if (leftTaken + rightTaken
> (left + 1 ) + (N - right)) {
leftTaken = left + 1 ;
rightTaken = N - right;
}
break ;
}
if (leftSum + rightSum > K)
break ;
}
}
if (leftTaken + rightTaken <= N) {
for ( int i = 0 ; i < leftTaken; i++)
System.out.print( A[i] + " " );
for ( int i = 0 ; i < rightTaken; i++)
System.out.print(A[N - i - 1 ] + " " );
}
else
System.out.print(- 1 );
}
public static void main(String[] args)
{
int N = 7 ;
int A[] = { 3 , 2 , 1 , 1 , 1 , 1 , 3 };
int K = 10 ;
minSizeArr(A, N, K);
}
}
|
Python3
def minSizeArr(A, N, K):
leftTaken = N
rightTaken = N
leftSum = 0
rightSum = 0
for left in range ( - 1 , N):
if (left ! = - 1 ):
leftSum + = A[left]
rightSum = 0
for right in range (N - 1 , left, - 1 ):
rightSum + = A[right]
if (leftSum + rightSum = = K):
if (leftTaken + rightTaken >
(left + 1 ) + (N - right)):
leftTaken = left + 1
rightTaken = N - right
break
if (leftSum + rightSum > K):
break
if (leftTaken + rightTaken < = N):
for i in range (leftTaken):
print (A[i], end = " " )
for i in range (rightTaken):
print (A[N - i - 1 ], end = " " )
else :
print ( - 1 )
if __name__ = = "__main__" :
N = 7
A = [ 3 , 2 , 1 , 1 , 1 , 1 , 3 ]
K = 10
minSizeArr(A, N, K)
|
C#
using System;
class GFG {
static void minSizeArr( int [] A, int N, int K)
{
int leftTaken = N, rightTaken = N;
int leftSum = 0, rightSum = 0;
for ( int left = -1; left < N; left++) {
if (left != -1)
leftSum += A[left];
rightSum = 0;
for ( int right = N - 1; right > left; right--)
{
rightSum += A[right];
if (leftSum + rightSum == K) {
if (leftTaken + rightTaken
> (left + 1) + (N - right)) {
leftTaken = left + 1;
rightTaken = N - right;
}
break ;
}
if (leftSum + rightSum > K)
break ;
}
}
if (leftTaken + rightTaken <= N) {
for ( int i = 0; i < leftTaken; i++)
Console.Write( A[i] + " " );
for ( int i = 0; i < rightTaken; i++)
Console.Write(A[N - i - 1] + " " );
}
else
Console.Write(-1);
}
public static void Main()
{
int N = 7;
int [] A = { 3, 2, 1, 1, 1, 1, 3 };
int K = 10;
minSizeArr(A, N, K);
}
}
|
Javascript
<script>
function minSizeArr(A, N, K)
{
let leftTaken = N, rightTaken = N;
let leftSum = 0, rightSum = 0;
for (let left = -1; left < N; left++) {
if (left != -1)
leftSum += A[left];
rightSum = 0;
for (let right = N - 1; right > left; right--)
{
rightSum += A[right];
if (leftSum + rightSum == K) {
if (leftTaken + rightTaken
> (left + 1) + (N - right)) {
leftTaken = left + 1;
rightTaken = N - right;
}
break ;
}
if (leftSum + rightSum > K)
break ;
}
}
if (leftTaken + rightTaken <= N) {
for (let i = 0; i < leftTaken; i++)
document.write( A[i] + " " );
for (let i = 0; i < rightTaken; i++)
document.write(A[N - i - 1] + " " );
}
else
document.write(-1);
}
let N = 7;
let A = [ 3, 2, 1, 1, 1, 1, 3 ];
let K = 10;
minSizeArr(A, N, K);
</script>
|
Time Complexity: O(N2)
Auxiliary Space: O(1)
Efficient Approach: Follow the steps below to optimize the above approach:
- Calculate the sum of elements of the array A[] and store it in a variable, say Total.
- The problem can be seen as finding the maximum size subarray with sum (Total – K).
- The remaining elements will add up to K.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void minSizeArr( int A[], int N, int K)
{
int sum = 0;
for ( int i = 0; i < N; i++)
sum += A[i];
if (K > sum) {
cout << -1;
return ;
}
if (K == sum) {
for ( int i = 0; i < N; i++) {
cout << A[i] << " " ;
}
return ;
}
int tar = sum - K;
unordered_map< int , int > um;
um[0] = -1;
int left, right;
int cur = 0, maxi = -1;
for ( int i = 0; i < N; i++) {
cur += A[i];
if (um.find(cur - tar) != um.end()
&& i - um[cur - tar] > maxi) {
maxi = i - um[cur - tar];
right = i;
left = um[cur - tar];
}
if (um.find(cur) == um.end())
um[cur] = i;
}
if (maxi == -1)
cout << -1;
else {
for ( int i = 0; i <= left; i++)
cout << A[i] << " " ;
for ( int i = 0; i < right; i++)
cout << A[N - i - 1] << " " ;
}
}
int main()
{
int N = 7;
int A[] = { 3, 2, 1, 1, 1, 1, 3 };
int K = 10;
minSizeArr(A, N, K);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static void minSizeArr( int A[], int N, int K)
{
int sum = 0 ;
for ( int i = 0 ; i < N; i++)
sum += A[i];
if (K > sum) {
System.out.print(- 1 );
return ;
}
if (K == sum) {
for ( int i = 0 ; i < N; i++) {
System.out.print(A[i] + " " );
}
return ;
}
int tar = sum - K;
HashMap<Integer, Integer> um = new HashMap<Integer, Integer>();
um.put( 0 , - 1 );
int left = 0 , right = 0 ;
int cur = 0 , maxi = - 1 ;
for ( int i = 0 ; i < N; i++) {
cur += A[i];
if (um.containsKey(cur - tar)
&& i - um.get(cur - tar) > maxi) {
maxi = i - um.get(cur - tar);
right = i;
left = um.get(cur - tar);
}
if (!um.containsKey(cur))
um.put(cur, i);
}
if (maxi == - 1 )
System.out.println(- 1 );
else {
for ( int i = 0 ; i <= left; i++)
System.out.print(A[i] + " " );
for ( int i = 0 ; i < right; i++)
System.out.print(A[N - i - 1 ] + " " );
}
}
public static void main (String[] args) {
int N = 7 ;
int A[] = { 3 , 2 , 1 , 1 , 1 , 1 , 3 };
int K = 10 ;
minSizeArr(A, N, K);
}
}
|
Python3
def minSizeArr(A, N, K):
sum = 0
for i in range (N):
sum + = A[i]
if (K > sum ):
print ( - 1 );
return
if (K = = sum ):
for i in range (N):
print (A[i],end = " " )
return
tar = sum - K
um = {}
um[ 0 ] = - 1
left = 0
right = 0
cur = 0
maxi = - 1
for i in range (N):
cur + = A[i]
if ((cur - tar) in um and (i - um[cur - tar]) > maxi):
maxi = i - um[cur - tar]
right = i
left = um[cur - tar]
if (cur not in um):
um[cur] = i
if (maxi = = - 1 ):
print ( - 1 )
else :
for i in range (left + 1 ):
print (A[i], end = " " )
for i in range (right):
print (A[N - i - 1 ], end = " " )
if __name__ = = '__main__' :
N = 7
A = [ 3 , 2 , 1 , 1 , 1 , 1 , 3 ]
K = 10
minSizeArr(A, N, K)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static void minSizeArr( int [] A, int N, int K)
{
int sum = 0;
for ( int i = 0; i < N; i++)
sum += A[i];
if (K > sum)
{
Console.WriteLine(-1);
return ;
}
if (K == sum)
{
for ( int i = 0; i < N; i++)
{
Console.Write(A[i] + " " );
}
return ;
}
int tar = sum - K;
Dictionary< int ,
int > um = new Dictionary< int ,
int >();
um[0] = -1;
int left = 0, right = 0;
int cur = 0, maxi = -1;
for ( int i = 0; i < N; i++)
{
cur += A[i];
if (um.ContainsKey(cur - tar) &&
i - um[cur - tar] > maxi)
{
maxi = i - um[cur - tar];
right = i;
left = um[cur - tar];
}
if (!um.ContainsKey(cur))
um[cur] = i;
}
if (maxi == -1)
Console.Write(-1);
else
{
for ( int i = 0; i <= left; i++)
Console.Write(A[i] + " " );
for ( int i = 0; i < right; i++)
Console.Write(A[N - i - 1] + " " );
}
}
static public void Main()
{
int N = 7;
int [] A = { 3, 2, 1, 1, 1, 1, 3 };
int K = 10;
minSizeArr(A, N, K);
}
}
|
Javascript
<script>
function minSizeArr(A, N, K)
{
var sum = 0;
var i;
for (i = 0; i < N; i++)
sum += A[i];
if (K > sum) {
cout << -1;
return ;
}
if (K == sum) {
for (i = 0; i < N; i++) {
document.write(A[i]+ ' ' );
}
return ;
}
var tar = sum - K;
var um = new Map();
um[0] = -1;
var left, right;
var cur = 0, maxi = -1;
for (i = 0; i < N; i++) {
cur += A[i];
if (um.has(cur - tar)
&& i - um.get(cur - tar) > maxi) {
maxi = i - um.get(cur - tar);
right = i;
left = um.get(cur - tar);
}
if (!um.has(cur))
um.set(cur,i);
}
if (maxi == -1)
cout << -1;
else {
for (i = 0; i <= left; i++)
document.write(A[i]+ ' ' );
for (i = 0; i < right; i++)
document.write(A[N - i - 1]+ ' ' );
}
}
var N = 7;
var A = [3, 2, 1, 1, 1, 1, 3];
var K = 10;
minSizeArr(A, N, K);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Related Topic: Subarrays, Subsequences, and Subsets in Array