题目链接:https://leetcode.cn/contest/biweekly-contest-100/
# 将钱分给最多的儿童
# 解题思路
按照题目分情况讨论即可
# 提交结果
# 代码
class Solution { | |
public int distMoney(int money, int children) { | |
if (children > money) return -1; | |
if (children * 8 > money) { | |
int x = money / 8; | |
int y = money % 8; | |
if (children - x == 1 && y == 4) return x - 1; | |
// 每人分一美元后,再看还有多少组 7 美元即可 | |
return (money - children) / 7; | |
} else if (children * 8 < money) { | |
return children - 1; | |
} else { | |
return children; | |
} | |
} | |
} | |
# [最大化数组的伟大值](https://leetcode.cn/problems/maximize-greatness-of-an-array/) | |
## 解题思路:贪心 + 双指针 | |
整个数组排序后,始终拿最大的与第二大的配对,如果相等,则需要与更小的配对;如果大于,结果直接加一,继续给剩余最大的数进行配对;直到遍历完整个数组。 | |
## 代码 | |
``` java | |
class Solution { | |
public int maximizeGreatness(int[] nums) { | |
Arrays.sort(nums); | |
int n = nums.length; | |
int k = n -1; | |
int ret = 0; | |
for (int i = n - 2; i >= 0; --i) { | |
if (nums[k] > nums[i]) { | |
++ret; | |
--k; | |
} | |
} | |
return ret; | |
} | |
} |
# 标记所有元素后数组的分数
# 思路:模拟 + 排序优化
按照题意模拟即可,只不过可以加快每次寻找最小值的速度,用数组同时保存 nums[i]
与 i
,再进行升序排序,这样依次取到最小的数,同时用原数组进行标记已经被标记的数,直接赋值 -1
即可。
# 代码
class Solution { | |
public long findScore(int[] nums) { | |
int n = nums.length; | |
int[][] arr = new int[n][2]; | |
for (int i = 0; i < n; ++i) { | |
arr[i][0] = i; | |
arr[i][1] = nums[i]; | |
} | |
Arrays.sort(arr, (o1, o2) -> o1[1] == o2[1] ? o1[0] - o2[0] : o1[1] - o2[1]); | |
long score = 0; | |
for (int i = 0; i < n; ++i) { | |
int j = arr[i][0]; | |
if (nums[j] > -1) { | |
// 当前最小值可选 | |
score += arr[i][1]; | |
// 标记周围的数 | |
if (j > 0) nums[j - 1] = -1; | |
if (j < n - 1) nums[j + 1] = -1; | |
} | |
} | |
return score; | |
} | |
} |
# 修车的最少时间
# 法一:暴力
对每一辆车分配给当前能最快完成修理工作的工人,这里就需要记录每位工人修理的汽车数量。为了能较快地找到当前修理最快的工人,根据修理当前车辆所花时间建立小顶堆。
# 代码
class Solution { | |
public long repairCars(int[] ranks, int cars) { | |
int n = ranks.length; | |
long spend = 0; | |
// 每位工人修车的数量 | |
int[] rc = new int[n]; | |
Arrays.fill(rc, 1); | |
PriorityQueue<Integer> pq = new PriorityQueue<>((o1, o2) -> { | |
long l1 = (long) ranks[o1] * rc[o1] * rc[o1]; | |
long l2 = (long) ranks[o2] * rc[o2] * rc[o2]; | |
return (int) (l1 - l2); | |
}); | |
for (int i = 0; i < n; ++i) pq.offer(i); | |
for (int k = 1; k <= cars; ++k) { | |
// 第 k 辆车交给谁来修 | |
// 选择花费时间最小的工人 | |
int j = pq.poll(); | |
long min = (long) ranks[j] * rc[j] * rc[j]; | |
spend = Math.max(spend, min); | |
// 累加当前工人的修车数量 | |
++rc[j]; | |
pq.offer(j); | |
} | |
return spend; | |
} | |
} |
当前时间复杂度:O (n*logn),有超时的风险!
# 法二:二分法
参考:https://leetcode.cn/problems/minimum-time-to-repair-cars/solution/er-fen-da-an-pythonjavacgo-by-endlessche-keqf/
# 代码
class Solution { | |
public long repairCars(int[] ranks, int cars) { | |
long min = Arrays.stream(ranks).min().orElse(0); | |
long l = 0, r = min * cars * cars; | |
while (l + 1 < r) { | |
long m = (l + r) / 2; | |
long t = 0; | |
for (int g : ranks) { | |
t += Math.sqrt(m / g); | |
} | |
if (t >= cars) r = m; | |
else l = m; | |
} | |
return r; | |
} | |
} |