哎,第一次参加周赛就被折磨,最怕贪心的题,结果第一题就贪心,心态崩了!
6112. 装满杯子需要的最短总时长
贪心做法:https://leetcode.cn/problems/minimum-amount-of-time-to-fill-cups/solution/by-tsreaper-158c/
获得三个杯子的最大最小和中间的杯子数,直接排序即可获得。记为a(最小),b(中间),c(最大)。
- 如果a + b <= c,此时不管怎么装,都必须以装满最大的,所以以最大的为准
- 如果a + b > c,此时就需要把超出的杯子进行均分,但均分需要分奇数和偶数,t = a+b- c
- 如果 t 为偶数,那么我们可以把t/2,进行内部消化,操作过后就有 a + b = c,所以答案:t / 2 + c
- 如果t为奇数,那么可以把(t - 1) / 2 进行内部消化,操作过后就有a + b - 1 = c,所以答案: (t-1)/2 + c +1
总体复杂度 O(1)。
class Solution {
public int fillCups(int[] amount) {
Arrays.sort(amount);
if(amount[0] + amount[1] <= amount[2]) return amount[2];
else {
int t = amount[1] + amount[0] - amount[2];
// 处理了一下,+1直接不用判断
return (t + 1) / 2 + amount[2];
}
}
}
6113. 无限集中的最小数字
哈希表模拟:https://leetcode.cn/problems/smallest-number-in-infinite-set/solution/by-tsreaper-64gp/
注意题目给的整数范围1 <= num <=1000(当时没看见….)
由于知道了整数的范围,所以我们使用一个hash表来记录不存在的整数。
- popSmallest获取最小值:遍历1~1000,取hash表中第一个不存在的数,弹出后注意保存到hash表中。
addBack添加元素:直接从hash表中删除
class SmallestInfiniteSet {
Set<Integer> set = new HashSet<>();
public SmallestInfiniteSet() {
}
public int popSmallest() {
int i = 1;
for(; i <= 1000;i++) {
if(!set.contains(i)) {
set.add(i);
return i;
}
}
return i;
}
public void addBack(int num) {
set.remove(num);
}
}
6114. 移动片段得到字符串
class Solution {
// 首先,无论怎么移动,由于 L 和 R 无法互相穿过对方,那么去掉 _ 后的剩余字符应该是相同的,否则返回 false。
// 然后用双指针遍历 start[i] 和 target[j],分类讨论:
// 如果当前为L,如果i < j,因为L无法向右移动,所以返回false
// 同理,如果当前为R,如果i > j,因为R无法向左移动,所以返回false
public boolean canChange(String start, String target) {
// 如果去掉_不相等,那么该字符串不匹配
if (!start.replaceAll("_", "").equals(target.replaceAll("_", ""))) return false;
for (int i = 0, j = 0; i < start.length(); i++) {
// 等于 _ 跳过,找到L 或者 R 才进行匹配
if (start.charAt(i) == '_') continue;
while (target.charAt(j) == '_') j++;
// 简写
// if (i != j && (start.charAt(i) == 'L') != (i > j)) return false;
if (i != j) {
if (start.charAt(i) == 'L' && i < j) return false;
if (start.charAt(i) == 'R' && i > j) return false;
}
j++;
}
return true;
}
}
6115
不会!