1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class Solution { private int modulo = 1000000007;
public int maxPerformance(int n, int[] speed, int[] efficiency, int k) { List<int[]> engineers = new ArrayList<>(); for (int i = 0; i < speed.length; i++) { engineers.add(new int[] { efficiency[i], speed[i] }); } Collections.sort(engineers, (a, b) -> a[0] != b[0] ? a[0] - b[0] : b[1] - a[1]); long ans = 0; for (int i = 0; i < n; i++) { if (i > 0 && engineers.get(i)[0] == engineers.get(i - 1)[0]) continue; PriorityQueue<int[]> candidates = new PriorityQueue<>((a, b) -> a[1] - b[1]); for (int j = i + 1; j < n; j++) { candidates.offer(engineers.get(j)); if (candidates.size() == k) { candidates.poll(); } } long speedSum = engineers.get(i)[1]; while (!candidates.isEmpty()) { speedSum += candidates.poll()[1]; } long currPerfor = speedSum * engineers.get(i)[0]; ans = Math.max(ans, currPerfor); } return (int) (ans % modulo); } }
|
这个想法是对的, 但是需要改进一些些. 就是穷举, 让每一个engineer都成为efficiency最小的那个, 看这种情况下最大的perf是多少. 然后让每一个engineer当一遍, 这样就能取到最大值了.
试着按照efficiency由大到小排序. 如果从小到大, 我们每次都要往后遍历到头然后找出k - 1个合适的人选. 如果从大到小, 那么我们可以把之前存在PQ中的候选人留着, 这样能够重复利用之前的计算.
这个时间复杂度就很高了第一个iteration是(n - 1)log(n - 1), 然后是(n - 2)log(n - 2)….
空间复杂度: O(n) 因为用了PQ和engineers这个list.
看看下面的方法.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class Solution { private int modulo = 1000000007;
public int maxPerformance(int n, int[] speed, int[] efficiency, int k) { List<int[]> engineers = new ArrayList<>(); for (int i = 0; i < speed.length; i++) { engineers.add(new int[] { efficiency[i], speed[i] }); } Collections.sort(engineers, (a, b) -> b[0] - a[0]); long ans = 0; long currSpeed = 0; PriorityQueue<int[]> candidates = new PriorityQueue<>((a, b) -> a[1] - b[1]); for (int i = 0; i < n; i++) { if (candidates.size() == k) { currSpeed -= candidates.poll()[1]; } candidates.offer(engineers.get(i)); currSpeed += engineers.get(i)[1]; long currEfficiency = engineers.get(i)[0]; long currPerf = currSpeed * currEfficiency; ans = Math.max(ans, currPerf); } return (int) (ans % modulo); } }
|
需要注意的是, 我们始终记录PQ中所有engineers的speed sum是多少.
时间复杂度: O(nlogn + nlogk) nlogn是开始的时候sort了一下, 一次之后每次都对PQ进行操作.
空间复杂度: O(n) 用了engineers这个list以及PQ.