配列のXNUMXつのサブセットの可能な最大差


難易度 ハード
よく聞かれる アトラシアン ケイデンスインド ディレクティ 費用無料 Opera PayU Snapchat タイムズインターネット ゾーメ
配列 ハッシュ 並べ替え(ソート)

あるとしましょう 整数 配列。 問題ステートメント「配列のXNUMXつのサブセットの可能な最大の差」は、配列のXNUMXつのサブセット間の可能な最大の差を見つけることを求めています。

従うべき条件:

  • 配列には繰り返し要素を含めることができますが、要素の最高頻度は2を超えてはなりません。
  • それぞれの要素の合計の差が最大になるように、XNUMXつのサブセットを作成する必要があります。
  • 配列のすべての要素は、要素を残さずにXNUMXつのサブセットに分割する必要があります。
  • XNUMXつの要素は、サブセット内で同じであってはなりません。

配列のXNUMXつのサブセットの可能な最大差

arr[] = {2, 5, -3, -1, 5, 7}
13

説明

サブセット→(2、7、5)-(-3、-1、5)= 13

{1, 5, 3, -1, -5, 6}
21

説明

サブセット→(1、3、5、6)–(-5、-1)= 21

アルゴリズム

  1. XNUMXつ宣言する 地図、XNUMXつは正の要素用、もうXNUMXつは負の要素用です。
  2. 正の要素とその数をXNUMXつのマップに保存します。
  3. 頻度1のすべての正の要素を合計し、次の場所に保存します。 サブセット1.
  4. 負の要素とその数を別のマップに保存します。
  5. 頻度1のすべての負の要素を合計し、次の場所に保存します。 サブセット2.
  6. 戻り値subset1-subset2。

説明

私たちは与えました 配列、XNUMXつのサブセットの要素の合計の違いを見つける必要があり、それが最大になるはずです。 を使用します 地図. ハッシング この質問を解決するための効率的な方法を提供します。 XNUMXつのマップを使用します。 XNUMXつは正の要素に対して実行された操作用で、もうXNUMXつは負の要素に対して実行された操作用です。 配列には正の要素と負の要素の両方を含めることができるため、それも処理する必要があります。

配列とマップを取ります。 配列の各要素を選択し、それが0より大きいかどうかを確認します。次に、出現回数とともにマップに格納します。 正の要素の頻度を格納した後、0より大きく、頻度が1しかない配列のすべての値を合計します。つまり、複数回または複数回出現する要素を無視する必要があります。

負の要素についても同じことが行われます。配列のすべての要素を選択し、今度はそれが0未満かどうかを確認します。マップに格納し(正の数にします)、その数を発生。 負の要素の頻度を格納した後、0未満で、頻度が1しかない配列のすべての値を合計します。ここでも、数回以上来る要素を無視する必要があります。一度より。

すべての正と負の要素の合計を取得した後、頻度1のみの要素を条件として、両方の合計の差を返す必要があります。これが答えになります。

コード

配列のXNUMXつのサブセットの可能な最大差を見つけるためのC ++コード

#include<iostream>
#include<unordered_map>

using namespace std;

int maxDiff(int arr[], int n)
{
    unordered_map<int, int> positiveElement;
    unordered_map<int, int> negativeElement;

    int sumSubset1 = 0, sumSubset2 = 0;
    for (int i = 0; i <= n - 1; i++)
        if (arr[i] > 0)
            positiveElement[arr[i]]++;

    for (int i = 0; i <= n - 1; i++)
        if (arr[i] > 0 && positiveElement[arr[i]] == 1)
            sumSubset1 += arr[i];

    for (int i = 0; i <= n - 1; i++)
        if (arr[i] < 0)
            negativeElement[abs(arr[i])]++;

    for (int i = 0; i <= n - 1; i++)
        if (arr[i] < 0 &&
                negativeElement[abs(arr[i])] == 1)
            sumSubset2 += arr[i];

    return abs(sumSubset1 - sumSubset2);
}
int main()
{
    int arr[] = {2,5,-3,-1,5,7};
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "Maximum difference found is: " << maxDiff(arr, n);
    return 0;
}
Maximum difference found is: 13

配列のXNUMXつのサブセットの可能な最大差を見つけるJavaコード

import java.util.HashMap;
class SubsetDifference
{
    public static int getDifference(int arr[], int n)
    {
        HashMap<Integer, Integer> positiveElement=new HashMap<Integer, Integer>();
        HashMap<Integer, Integer> negativeElement=new HashMap<Integer, Integer>();
        int sumSubset1 = 0, sumSubset2 = 0;
        for (int i = 0; i <= n - 1; i++)
        {
            if (arr[i] > 0)
            {
                if(positiveElement.containsKey(arr[i]))
                    positiveElement.put(arr[i],positiveElement.get(arr[i])+1);
                else
                    positiveElement.put(arr[i],1);
            }
        }
        for (int i = 0; i <= n - 1; i++)
            if (arr[i] > 0 && positiveElement.get(arr[i]) == 1)
                sumSubset1 += arr[i];

        for (int i = 0; i <= n - 1; i++)
        {
            if (arr[i] < 0)
            {
                if(negativeElement.containsKey(Math.abs(arr[i])))
                    negativeElement.put(Math.abs(arr[i]),negativeElement.get(Math.abs(arr[i]))+1);
                else
                    negativeElement.put(Math.abs(arr[i]),1);
            }
        }
        for (int i = 0; i <= n - 1; i++)
            if (arr[i] < 0 && negativeElement.get(Math.abs(arr[i]))== 1)
                sumSubset2 += arr[i];

        return Math.abs(sumSubset1 - sumSubset2);
    }
    public static void main(String [] args)
    {
        int arr[] = {2,5,-3,-1,5,7};
        int n = arr.length;
        System.out.println("Maximum difference found is:"+getDifference(arr, n));
    }
}
Maximum difference found is:13

複雑さの分析

時間の複雑さ

O(N) where 「n」 配列内の要素の数です。 HashMapを使用したため、O(1)で挿入/削除/検索を実行できます。

スペースの複雑さ

O(N) where 「n」 配列の要素数です。