给定一个由N 个整数组成的数组arr[] ,任务是打印通过将数组拆分为两个子集而获得的两个子集中较小的一个,从而使较小子集的总和最大化。
例子:
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
方法:给定的问题可以通过使用散列和排序来解决。
请按照以下步骤解决问题:
- 初始化一个 HashMap,比如M ,以存储数组arr[]中每个字符的频率。
- 遍历数组arr[]并增加 HashMap M中每个字符的计数。
- 初始化 2 个变量,例如S和flag ,以存储第一个子集的总和并分别存储答案是否存在。
- 按升序对数组arr[]进行排序。
- 初始化一个 ArrayList,比如ans ,以存储结果子集的元素。
- 以相反的顺序遍历数组arr[]并执行以下步骤:
- 将当前字符的频率存储在一个变量中,比如F 。
- 如果(F + ans.size())小于 ( N – (F + ans.size()))然后将元素arr[i]附加到 ArrayList ans F number of 次。
- 将i的值减少F 。
- 如果S的值大于数组元素的总和,则将标志标记为真然后中断。
- 完成上述步骤后,如果flag 的值为true ,则打印 ArrayList ans作为结果子集。否则,打印-1 .the
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to split array elements
// into two subsets having sum of
// the smaller subset maximized
static void findSubset(vector arr)
{
// Stores the size of the array
int N = arr.size();
// Stores the frequency
// of array elements
map mp;
// Stores the total
// sum of the array
int totSum = 0;
// Stores the sum of
// the resultant set
int s = 0;
// Stores if it is possible
// to split the array that
// satisfies the conditions
int flag = 0;
// Stores the elements
// of the first subseta
vector ans;
// Traverse the array arr[]
for (int i = 0;
i < arr.size(); i++) {
// Increment total sum
totSum += arr[i];
// Increment count of arr[i]
mp[arr[i]]=mp[arr[i]]+1;
}
// Sort the array arr[]
sort(arr.begin(),arr.end());
// Stores the index of the
// last element of the array
int i = N - 1;
// Traverse the array arr[]
while (i >= 0) {
// Stores the frequency
// of arr[i]
int frq = mp[arr[i]];
// If frq + ans.size() is
// at most remaining size
if ((frq + ans.size())
< (N - (frq + ans.size())))
{
for (int k = 0; k < frq; k++)
{
// Append arr[i] to ans
ans.push_back(arr[i]);
// Decrement totSum by arr[i]
totSum -= arr[i];
// Increment s by arr[i]
s += arr[i];
i--;
}
}
// Otherwise, decrement i
// by frq
else {
i -= frq;
}
// If s is greater
// than totSum
if (s > totSum) {
// Mark flag 1
flag = 1;
break;
}
}
// If flag is equal to 1
if (flag == 1) {
// Print the arrList ans
for (i = ans.size() - 1;
i >= 0; i--) {
cout< arr = { 5, 3, 2, 4, 1, 2 };
findSubset(arr);
}
// This code is contributed by mohit kumar 29.
Java
// Java program for above approach
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG {
// Function to split array elements
// into two subsets having sum of
// the smaller subset maximized
static void findSubset(int[] arr)
{
// Stores the size of the array
int N = arr.length;
// Stores the frequency
// of array elements
Map map
= new HashMap<>();
// Stores the total
// sum of the array
int totSum = 0;
// Stores the sum of
// the resultant set
int s = 0;
// Stores if it is possible
// to split the array that
// satisfies the conditions
int flag = 0;
// Stores the elements
// of the first subset
ArrayList ans
= new ArrayList<>();
// Traverse the array arr[]
for (int i = 0;
i < arr.length; i++) {
// Increment total sum
totSum += arr[i];
// Increment count of arr[i]
map.put(arr[i],
map.getOrDefault(
arr[i], 0)
+ 1);
}
// Sort the array arr[]
Arrays.sort(arr);
// Stores the index of the
// last element of the array
int i = N - 1;
// Traverse the array arr[]
while (i >= 0) {
// Stores the frequency
// of arr[i]
int frq = map.get(arr[i]);
// If frq + ans.size() is
// at most remaining size
if ((frq + ans.size())
< (N - (frq + ans.size()))) {
for (int k = 0; k < frq; k++) {
// Append arr[i] to ans
ans.add(arr[i]);
// Decrement totSum by arr[i]
totSum -= arr[i];
// Increment s by arr[i]
s += arr[i];
i--;
}
}
// Otherwise, decrement i
// by frq
else {
i -= frq;
}
// If s is greater
// than totSum
if (s > totSum) {
// Mark flag 1
flag = 1;
break;
}
}
// If flag is equal to 1
if (flag == 1) {
// Print the arrList ans
for (i = ans.size() - 1;
i >= 0; i--) {
System.out.print(
ans.get(i) + " ");
}
}
// Otherwise, print "-1"
else {
System.out.print(-1);
}
}
// Driver Code
public static void main(String[] args)
{
int[] arr = { 5, 3, 2, 4, 1, 2 };
findSubset(arr);
}
}
Python3
# Python 3 program for the above approach
from collections import defaultdict
# Function to split array elements
# into two subsets having sum of
# the smaller subset maximized
def findSubset(arr):
# Stores the size of the array
N = len(arr)
# Stores the frequency
# of array elements
mp = defaultdict(int)
# Stores the total
# sum of the array
totSum = 0
# Stores the sum of
# the resultant set
s = 0
# Stores if it is possible
# to split the array that
# satisfies the conditions
flag = 0
# Stores the elements
# of the first subseta
ans = []
# Traverse the array arr[]
for i in range(len(arr)):
# Increment total sum
totSum += arr[i]
# Increment count of arr[i]
mp[arr[i]] = mp[arr[i]]+1
# Sort the array arr[]
arr.sort()
# Stores the index of the
# last element of the array
i = N - 1
# Traverse the array arr[]
while (i >= 0):
# Stores the frequency
# of arr[i]
frq = mp[arr[i]]
# If frq + ans.size() is
# at most remaining size
if ((frq + len(ans))
< (N - (frq + len(ans)))):
for k in range(frq):
# Append arr[i] to ans
ans.append(arr[i])
# Decrement totSum by arr[i]
totSum -= arr[i]
# Increment s by arr[i]
s += arr[i]
i -= 1
# Otherwise, decrement i
# by frq
else:
i -= frq
# If s is greater
# than totSum
if (s > totSum):
# Mark flag 1
flag = 1
break
# If flag is equal to 1
if (flag == 1):
# Print the arrList ans
for i in range(len(ans) - 1, -1, -1):
print(ans[i], end = " ")
# Otherwise, print "-1"
else:
print(-1)
# Driver Code
if __name__ == "__main__":
arr = [5, 3, 2, 4, 1, 2]
findSubset(arr)
# This code is contributed by ukasp.
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to split array elements
// into two subsets having sum of
// the smaller subset maximized
static void findSubset(List arr)
{
// Stores the size of the array
int N = arr.Count;
int i;
// Stores the frequency
// of array elements
Dictionary mp = new Dictionary();
// Stores the total
// sum of the array
int totSum = 0;
// Stores the sum of
// the resultant set
int s = 0;
// Stores if it is possible
// to split the array that
// satisfies the conditions
int flag = 0;
// Stores the elements
// of the first subseta
List ans = new List();
// Traverse the array arr[]
for (i = 0;
i < arr.Count; i++) {
// Increment total sum
totSum += arr[i];
// Increment count of arr[i]
if(mp.ContainsKey(arr[i]))
mp[arr[i]]=mp[arr[i]]+1;
else
mp.Add(arr[i],1);
}
// Sort the array arr[]
arr.Sort();
// Stores the index of the
// last element of the array
i = N - 1;
// Traverse the array arr[]
while (i >= 0) {
// Stores the frequency
// of arr[i]
int frq = mp[arr[i]];
// If frq + ans.size() is
// at most remaining size
if ((frq + ans.Count)
< (N - (frq + ans.Count)))
{
for (int k = 0; k < frq; k++)
{
// Append arr[i] to ans
ans.Add(arr[i]);
// Decrement totSum by arr[i]
totSum -= arr[i];
// Increment s by arr[i]
s += arr[i];
i--;
}
}
// Otherwise, decrement i
// by frq
else {
i -= frq;
}
// If s is greater
// than totSum
if (s > totSum) {
// Mark flag 1
flag = 1;
break;
}
}
// If flag is equal to 1
if (flag == 1) {
// Print the arrList ans
for (i = ans.Count - 1;
i >= 0; i--) {
Console.Write(ans[i]+" ");
}
}
// Otherwise, print "-1"
else {
Console.Write(-1);
}
}
// Driver Code
public static void Main()
{
List arr = new List(){ 5, 3, 2, 4, 1, 2 };
findSubset(arr);
}
}
// This code is contributed by ipg2016107.
Javascript
输出:
4 5
时间复杂度: O(N*log N)
辅助空间: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live