leetcode 826

タイトル説明

いくつかの作業があります。難易度は[i]を表し、私の仕事の番目の難しさ、利益[i]を表すi番目の仕事に復帰。

今、私たちはいくつかの労働者を持っています。労働者は、[I]は、i番目の労働者の能力、すなわち、労働者のみが行うことができます少ない難易ワーカー[i]が働いています。

すべての労働者は仕事を手配することができますが、ジョブは複数回行うことができます。

たとえば、3人の労働者が同じ作業1、$ 3の総収入に対する報酬を完了しようとしていた場合。労働者はすべての作業を実行できない場合は、彼の収入は$ 0です。

私たちは、最大の利益がどのくらいある得ることができますか?

例:

入力:難易度= [2,4,6,8,10]、利益 = [10,20,30,40,50]、労働者= [4,5,6,7]
出力:100
説明:労働者が割り当てられています利益のために、それぞれの作業の困難されている[4,4,6,6-]、[20,20,30,30]の。
ヒント:

1 <= difficulty.length = profit.length <= 10000
1 <= worker.length <= 10000
困難[i]は、利益[i]は、作業者[I]的范围是[1、10 ^ 5]

アイデアとコード

== 80%を打つ==

public class Solution {
    public int maxProfitAssignment(int[] difficulty, int[] profit, int[] worker) {
        // map建立difficult与profit的一一对应关系
        Map<Integer, Integer> map = new HashMap<>();
        for (int d = 0; d < difficulty.length; d++) {
            Integer p = map.get(difficulty[d]);
            if (p == null){
                map.put(difficulty[d], profit[d]);
            } else {
                map.put(difficulty[d], Math.max(p,profit[d]));
            }
        }
        /*
        因为能做困难度大的工人肯定能做困难度小的工作,所以按照困难度从小到大的顺序处理一遍map中difficult与profit的对应关系。
        使得做困难度大的工作的收益要大于比它困难度小的工作的收益。
         */
        Arrays.sort(difficulty);
        for (int i = 1; i < difficulty.length; i++) {
            if (difficulty[i] == difficulty[i-1]) continue;
            if (map.get(difficulty[i]) < map.get(difficulty[i-1])) {
                map.put(difficulty[i], map.get(difficulty[i-1]));
            }
        }
        /*
        将difficult和worker从小到大排序,利用两个指针从小到大进行对应难度对应收益的查找。
         */
        int res = 0;
        Arrays.sort(worker);
        int w = 0, d = 0;
        while (w < worker.length){
            while (d < difficulty.length && worker[w] >= difficulty[d]) ++d;
            if (d-1 >= 0)
                res += map.get(difficulty[d-1]);
            ++w;
        }
        return res;
    }

    public static void main(String[] args) {
        int[] d = {85,47,57};
        int[] p = {24,66,99};
        int[] w = {40,25,25};
        int i = new Solution().maxProfitAssignment(d, p, w);
        System.out.println("i = " + i);
    }
}

問題の解決策

方法:ソート
アイデア

我々はサイズによってソートする機能を持っているように、我々は、任意の順序で労働者を考慮することができます。

我々は難易度の低いアクセスの度に作業している場合は、その利益はこれまでの最高でなければなりません。

アルゴリズム

私たちは、タスクのスケジュール設定を「両手」のアプローチを使用しています。私たちは、最高の利用可能な最大の利益を計上しました。労働者のスキル、または能力値を求めるあまり困難なタスク、および結果としての各能力値について。

import java.awt.Point;

class Solution {
    public int maxProfitAssignment(int[] difficulty, int[] profit, int[] worker) {
        int N = difficulty.length;
        Point[] jobs = new Point[N];
        for (int i = 0; i < N; ++i)
            jobs[i] = new Point(difficulty[i], profit[i]);
        Arrays.sort(jobs, (a, b) -> a.x - b.x);
        Arrays.sort(worker);

        int ans = 0, i = 0, best = 0;
        for (int skill: worker) {
            while (i < N && skill >= jobs[i].x)
                best = Math.max(best, jobs[i++].y);
            ans += best;
        }

        return ans;
    }
}

複雑性分析

  • 時間複雑:$ O(NlogN + QlogQ)Nは、タスクの数である$は、Qは、労働者の数です。
  • 宇宙複雑:$ O(N)$、余分なスペースの仕事。

    私の収穫

  • 使用java.awt.Pointの
  • Pointオブジェクトの掃引動作ソート:は、Arrays.sort(ジョブ、(a、b)は - >斧 - BX)。

おすすめ

転載: www.cnblogs.com/yfs123456/p/11870874.html