📌  相关文章
📜  通过将数组分成两个子集,可以得到最大和的最小子集

📅  最后修改于: 2021-04-29 13:03:46             🧑  作者: Mango

给定一个由N个整数组成的数组arr [] ,任务是打印通过将数组分为两个子集而获得的两个子集中的较小者,以使较小子集的总和最大化。

例子:

方法:可以通过使用哈希和排序来解决给定的问题。
请按照以下步骤解决问题:

  • 初始化一个HashMap,例如M ,以存储数组arr []的每个字符的频率。
  • 遍历数组arr []并增加HashMap M中每个字符的计数。
  • 初始化2个变量,例如Sflag ,以存储第一子集的总和并分别存储是否存在答案。
  • 以升序对数组arr []进行排序。
  • 初始化一个ArrayList,例如ans ,以存储结果子集的元素。
  • 以相反的顺序遍历数组arr []并执行以下步骤:
    • 将当前字符的频率存储在变量F中
    • 如果(F + ans.size())是小于(N – (F + ans.size())),然后追加该元素在该ArrayList ARR [I] ANSF 时代。
    • 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)