【Leetcode算法题】458. 可怜的小猪

By Long Luo

今天Leetcode的每日一题是:458. 可怜的小猪,题目如下:

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
458. 可怜的小猪

有buckets桶液体,其中正好有一桶含有毒药,其余装的都是水。它们从外观看起来都一样。为了弄清楚哪只水桶含有毒药,你可以喂一些猪喝,通过观察猪是否会死进行判断。不幸的是,你只有minutesToTest分钟时间来确定哪桶液体是有毒的。

喂猪的规则如下:

1. 选择若干活猪进行喂养
2. 可以允许小猪同时饮用任意数量的桶中的水,并且该过程不需要时间。
3. 小猪喝完水后,必须有minutesToDie分钟的冷却时间。在这段时间里,你只能观察,而不允许继续喂猪。
4. 过了minutesToDie分钟后,所有喝到毒药的猪都会死去,其他所有猪都会活下来。
5. 重复这一过程,直到时间用完。

给你桶的数目buckets,minutesToDie和minutesToTest,返回在规定时间内判断哪个桶有毒所需的最小猪数。

示例 1:
输入:buckets = 1000, minutesToDie = 15, minutesToTest = 60
输出:5

示例 2:
输入:buckets = 4, minutesToDie = 15, minutesToTest = 15
输出:2

示例 3:
输入:buckets = 4, minutesToDie = 15, minutesToTest = 30
输出:2

提示:
1 <= buckets <= 1000
1 <= minutesToDie <= minutesToTest <= 100

方法一:HashMap + 双指针

思路与算法:

代码如下所示:

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public List<Integer> findAnagrams(String s, String p) {
List<Integer> ans = new ArrayList<>();

int patLen = p.length();
int srcLen = s.length();
if (patLen > srcLen) {
return ans;
}

Map<Character, Integer> patMap = new HashMap<>();
for (char ch : p.toCharArray()) {
patMap.put(ch, patMap.getOrDefault(ch, 0) + 1);
}

int left = 0;
int right = left + patLen;
Map<Character, Integer> winMap = new HashMap<>();
for (int i = left; i < right; i++) {
char ch = s.charAt(i);
winMap.put(ch, winMap.getOrDefault(ch, 0) + 1);
}

if (patMap.equals(winMap)) {
ans.add(left);
}

while (right < srcLen) {
char chRight = s.charAt(right);
winMap.put(chRight, winMap.getOrDefault(chRight, 0) + 1);
char chLeft = s.charAt(left);
if (winMap.get(chLeft) == 1) {
winMap.remove(chLeft);
} else {
winMap.put(chLeft, winMap.get(chLeft) - 1);
}
left++;
right++;
if (patMap.equals(winMap)) {
ans.add(left);
}
}

return ans;
}

复杂度分析:

  • 时间复杂度:O(m+n)O(m + n),其中mm为数组中的元素数量, nn为数组中的元素数量

  • 空间复杂度:O(n)O(n)。记录初始状态和临时的乱序数组均需要存储nn个元素。