Woodyiiiiiii / LeetCode

My private record of Leetcode solution

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Leetcode 1383. Maximum Performance of a Team / 502. IPO

Woodyiiiiiii opened this issue · comments

1383. Maximum Performance of a Team / 502. IPO

这道题其实就是双周赛96的原题。

其实难点在于,要想到用什么方法

首先要从题目条件入手,题目要求sum(...) * min()最大,考虑到数组大小,对于sum,我们考虑能不能用前缀和;对于min,我们考虑能不能用排序。

接着,看到最多K个大小,然后又要保证乘积最大,所以我们要保证对于每个min,他的sum要最大。那么就想到用优先队列;而且,对于如何遍历所有的nums2,有两种顺序,一种是从小到大,另一种是从大到小,又考虑到递进的关系,我们选择逆向思维,从大到小进行累加。

class Solution {
    public int maxPerformance(int n, int[] speed, int[] efficiency, int k) {
        int[][] pairs = new int[n][2];
        for (int i = 0; i < n; ++i) {
            pairs[i][0] = speed[i];
            pairs[i][1] = efficiency[i];
        }

        Arrays.sort(pairs, (o1, o2) -> o2[1] - o1[1]);
        PriorityQueue<Integer> pq = new PriorityQueue<>();

        long sum = 0;
        long ans = 0;
        final int mod = (int) (1e9) + 7;
        for (int[] pair : pairs) {
            if (pq.size() < k) {
                pq.add(pair[0]);
                sum += pair[0];
            } else {
                sum -= pq.poll();
                sum += pair[0];
                pq.add(pair[0]);
            }
            ans = Math.max(ans, sum * pair[1]);
        }
        return (int) (ans % mod);
    }
}

Tips:

  1. 对于线性关系,考虑排序和heap
  2. 要从题目条件出发,挖掘其中的关系
  3. 取余要在最后结果中取余,而不是每次计算sum * pair[1]中,因为溢出时会影响比较

类似题目:

总结:
这类题型一般特征是:

  1. 两个数组
  2. 最值范围内求最大和

所以这样就涉及到每个值对应的各个范围元素,用排序+堆