给定一个由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())),然后追加该元素在该ArrayList ARR [I] ANS的F数 时代。
- 将i的值减F。
- 如果S的值大于数组元素的总和,则将标志标记为true ,然后中断。
- 完成上述步骤后,如果flag的值为true ,则将ArrayList ans打印为结果子集。否则,打印-1。
下面是上述方法的实现:
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);
}
}
输出:
4 5
时间复杂度: O(N * log N)
辅助空间: O(N)