870アドバンテージシャッフル(貪欲)

1.問題の説明:

サイズが等しい2つの配列AとBが与えられた場合、A [i]> B [i]を満たすインデックスiの数によって、Bに対するAの利点を説明できます。

Aの任意の配置を返し、Bに対する利点を最大化します。

例1:

入力:A = [2,7,11,15]、B = [1,10,4,11]
出力:[2,11,7,15]
例2:

入力:A = [12,24,8,32]、B = [13,25,32,11]
出力:[24,32,8,12]

ヒント:

1 <= A.length = B.length <= 10000
0 <= A [i] <= 10 ^ 9
0 <= B [i] <= 10 ^ 9

ソース:LeetCode
リンク:https ://leetcode-cn.com/problems/advantage-shuffle

2.思考分析:

①まず、問題を明確に理解する必要があります解決する必要があるのは、AとBの要素をペアにした後に勝つ最大確率の組み合わせです。戻り値は、Bの要素のA配置です。実際、それは単に私たちが以前に聞いた古典的な物語です:天地競馬、Baidu Encyclopediaにアクセスしてこれらの資料をチェックすることができ、タイトルの意味が非常に明確です

②この種の問題は貪欲な戦略を使用することを考えさせます。Aの現在の要素がBより大きくない場合、このような戦略を使用して、Aの現在の要素を現在のBで可能な限り大きくすることを望みます。要素、次にAの次の要素を前のBの要素と一致させます

③オフィシャルが提供するコードは実は比較的理解しやすい貪欲な戦略なので学ぶ価値はある基本的な実装方法は以下のとおり:

1)A配列とB配列のクローンを作成します。ソート前の配列は最終的な回答生成プロセスで使用する必要があるため、回答は前のB配列の順序に従って生成されます

2)クローンされたA配列とB配列を並べ替えます。並べ替え後、AB配列の要素のサイズ関係を簡単に見つけることができます。Map<Integer、Deque <Integer >>データ構造がマッピングに使用され、キーは現在のB配列の要素の値です。 、値は現在B配列と一致しているA配列の要素値です。なぜ両端キューを使用するのですか?配列の要素が重複しているため、同一の要素が複数存在する可能性があります(先入れ先出し機能が満たされている限り、キューを使用することもできます)。このとき、マップにマップする必要がある場合、値が通常のデータ型の場合は同じですキーの値(同じ要素がBに存在する)が上書きされる可能性があるため、キューを使用して要素を格納し、この問題を回避します

3)変数を使用して現在のB配列の一致する位置を記録し、ループでA配列をトラバースします。A配列の要素がB配列の要素より大きい場合、現在一致している要素をマップにマップします。B配列は一致しますこれらの要素がBの現在の要素と一致しないため、位置が1ビット下に移動し、それが別のキューに参加する場合、これらの要素はBの現在の要素と一致しないため、キューで一致しないこれらの要素を処理するのが最適です。

4)最後に、ループ内のマップのマッピング関係を確認し、現在の要素がBと一致するAの要素を見つけ、トラバーサルプロセスの配置を生成します。実際、プロセス全体は比較的簡単に理解できます。デバッグする最良の方法は、デバッグすることです、プロセスを理解しやすくします

3.コードは次のとおりです。

公式コードは次のとおりです。

class Solution {
    public int[] advantageCount(int[] A, int[] B) {
        int[] sortedA = A.clone();
        Arrays.sort(sortedA);
        int[] sortedB = B.clone();
        Arrays.sort(sortedB);
        Map<Integer, Deque<Integer>> assigned = new HashMap();
        for (int b: B) assigned.put(b, new LinkedList());
        Deque<Integer> remaining = new LinkedList();
        int j = 0;
        for (int a: sortedA) {
            if (a > sortedB[j]) {
                assigned.get(sortedB[j++]).add(a);
            } else {
                remaining.add(a);
            }
        }
        int[] ans = new int[B.length];
        for (int i = 0; i < B.length; ++i) {
            if (assigned.get(B[i]).size() > 0)
                ans[i] = assigned.get(B[i]).pop();
            else
                ans[i] = remaining.pop();
        }
        return ans;
    }
}

 

元の記事569件を公開 153のような 訪問数590,000+

おすすめ

転載: blog.csdn.net/qq_39445165/article/details/105340874