Smallest subset of maximum sum possible by splitting array into two subsets
Last Updated :
24 May, 2021
Given an array arr[] consisting of N integers, the task is to print the smaller of the two subsets obtained by splitting the array into two subsets such that the sum of the smaller subset is maximized.
Examples:
Input: arr[] = {5, 3, 2, 4, 1, 2}
Output: 4 5
Explanation:
Split the array into two subsets as {4, 5} and {1, 2, 2, 3}.
The subset {4, 5} is of minimum length, i.e. 2, having maximum sum = 4 + 5 = 9.
Input: arr[] = {20, 15, 20, 50, 20}
Output: 15 50
Approach: The given problem can be solved by using Hashing and Sorting.
Follow the steps below to solve the problem:
- Initialize a HashMap, say M, to store the frequency of each character of the array arr[].
- Traverse the array arr[] and increment the count of every character in the HashMap M.
- Initialize 2 variables, say S, and flag, to store the sum of the first subset and to store if an answer exists or not respectively.
- Sort the array arr[] in ascending order.
- Initialize an ArrayList, say ans, to store the elements of the resultant subset.
- Traverse the array arr[] in reverse order and perform the following steps:
- Store the frequency of the current character in a variable, say F.
- If (F + ans.size()) is less than (N – (F + ans.size())) then append the element arr[i] in the ArrayList ans F number of times.
- Decrement the value of i by F.
- If the value of S is greater than the sum of the array elements, then mark the flag as true and then break.
- After completing the above steps, if the value of flag is true, then print the ArrayList ans as the resultant subset. Otherwise, print -1.the
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
static void findSubset(vector< int > arr)
{
int N = arr.size();
map< int , int > mp;
int totSum = 0;
int s = 0;
int flag = 0;
vector< int > ans;
for ( int i = 0;
i < arr.size(); i++) {
totSum += arr[i];
mp[arr[i]]=mp[arr[i]]+1;
}
sort(arr.begin(),arr.end());
int i = N - 1;
while (i >= 0) {
int frq = mp[arr[i]];
if ((frq + ans.size())
< (N - (frq + ans.size())))
{
for ( int k = 0; k < frq; k++)
{
ans.push_back(arr[i]);
totSum -= arr[i];
s += arr[i];
i--;
}
}
else {
i -= frq;
}
if (s > totSum) {
flag = 1;
break ;
}
}
if (flag == 1) {
for (i = ans.size() - 1;
i >= 0; i--) {
cout<<ans[i]<< " " ;
}
}
else {
cout<<-1;
}
}
int main()
{
vector< int > arr = { 5, 3, 2, 4, 1, 2 };
findSubset(arr);
}
|
Java
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG {
static void findSubset( int [] arr)
{
int N = arr.length;
Map<Integer, Integer> map
= new HashMap<>();
int totSum = 0 ;
int s = 0 ;
int flag = 0 ;
ArrayList<Integer> ans
= new ArrayList<>();
for ( int i = 0 ;
i < arr.length; i++) {
totSum += arr[i];
map.put(arr[i],
map.getOrDefault(
arr[i], 0 )
+ 1 );
}
Arrays.sort(arr);
int i = N - 1 ;
while (i >= 0 ) {
int frq = map.get(arr[i]);
if ((frq + ans.size())
< (N - (frq + ans.size()))) {
for ( int k = 0 ; k < frq; k++) {
ans.add(arr[i]);
totSum -= arr[i];
s += arr[i];
i--;
}
}
else {
i -= frq;
}
if (s > totSum) {
flag = 1 ;
break ;
}
}
if (flag == 1 ) {
for (i = ans.size() - 1 ;
i >= 0 ; i--) {
System.out.print(
ans.get(i) + " " );
}
}
else {
System.out.print(- 1 );
}
}
public static void main(String[] args)
{
int [] arr = { 5 , 3 , 2 , 4 , 1 , 2 };
findSubset(arr);
}
}
|
Python3
from collections import defaultdict
def findSubset(arr):
N = len (arr)
mp = defaultdict( int )
totSum = 0
s = 0
flag = 0
ans = []
for i in range ( len (arr)):
totSum + = arr[i]
mp[arr[i]] = mp[arr[i]] + 1
arr.sort()
i = N - 1
while (i > = 0 ):
frq = mp[arr[i]]
if ((frq + len (ans))
< (N - (frq + len (ans)))):
for k in range (frq):
ans.append(arr[i])
totSum - = arr[i]
s + = arr[i]
i - = 1
else :
i - = frq
if (s > totSum):
flag = 1
break
if (flag = = 1 ):
for i in range ( len (ans) - 1 , - 1 , - 1 ):
print (ans[i], end = " " )
else :
print ( - 1 )
if __name__ = = "__main__" :
arr = [ 5 , 3 , 2 , 4 , 1 , 2 ]
findSubset(arr)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static void findSubset(List< int > arr)
{
int N = arr.Count;
int i;
Dictionary< int , int > mp = new Dictionary< int , int >();
int totSum = 0;
int s = 0;
int flag = 0;
List< int > ans = new List< int >();
for (i = 0;
i < arr.Count; i++) {
totSum += arr[i];
if (mp.ContainsKey(arr[i]))
mp[arr[i]]=mp[arr[i]]+1;
else
mp.Add(arr[i],1);
}
arr.Sort();
i = N - 1;
while (i >= 0) {
int frq = mp[arr[i]];
if ((frq + ans.Count)
< (N - (frq + ans.Count)))
{
for ( int k = 0; k < frq; k++)
{
ans.Add(arr[i]);
totSum -= arr[i];
s += arr[i];
i--;
}
}
else {
i -= frq;
}
if (s > totSum) {
flag = 1;
break ;
}
}
if (flag == 1) {
for (i = ans.Count - 1;
i >= 0; i--) {
Console.Write(ans[i]+ " " );
}
}
else {
Console.Write(-1);
}
}
public static void Main()
{
List< int > arr = new List< int >(){ 5, 3, 2, 4, 1, 2 };
findSubset(arr);
}
}
|
Javascript
<script>
function findSubset(arr)
{
var N = arr.length;
var mp = new Map();
var totSum = 0;
var s = 0;
var flag = 0;
var ans = [];
for ( var i = 0;
i < arr.length; i++) {
totSum += arr[i];
if (mp.has(arr[i]))
mp.set(arr[i], mp.get(arr[i])+1)
else
mp.set(arr[i], 1);
}
arr.sort((a,b)=> a-b)
var i = N - 1;
while (i >= 0) {
var frq = mp.get(arr[i]);
if ((frq + ans.length)
< (N - (frq + ans.length)))
{
for ( var k = 0; k < frq; k++)
{
ans.push(arr[i]);
totSum -= arr[i];
s += arr[i];
i--;
}
}
else {
i -= frq;
}
if (s > totSum) {
flag = 1;
break ;
}
}
if (flag == 1) {
for (i = ans.length - 1;
i >= 0; i--) {
document.write( ans[i] + " " );
}
}
else {
document.write(-1);
}
}
var arr = [5, 3, 2, 4, 1, 2 ];
findSubset(arr);
</script>
|
Time Complexity: O(N*log N)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...