Skip to content

Commit 08f1ff1

Browse files
committed
3476-3481-3491-3496-3506-3520-3526-3535-3540-3549 (10)
1 parent f808126 commit 08f1ff1

21 files changed

+932
-0
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import java.util.ArrayList;
2+
import java.util.HashMap;
3+
import java.util.List;
4+
import java.util.Map;
5+
6+
public class SolutionP3476 {
7+
public long maxProfit(int[] workers, int[][] tasks) {
8+
Map<Integer, List<Integer>> groupTasks = new HashMap<>(); // 按 task[0] 分组
9+
for (int[] ta : tasks) groupTasks.computeIfAbsent(ta[0], e -> new ArrayList<>()).add(ta[1]);
10+
for (List<Integer> vals : groupTasks.values()) vals.sort(null);
11+
12+
long ans = 0;
13+
for (int wo : workers) {
14+
if (!groupTasks.containsKey(wo)) continue;
15+
ans += groupTasks.get(wo).removeLast();
16+
if (groupTasks.get(wo).isEmpty()) groupTasks.remove(wo);
17+
}
18+
int maxTask = 0;
19+
for (List<Integer> vals : groupTasks.values()) {
20+
maxTask = Math.max(maxTask, vals.getLast());
21+
}
22+
return ans + maxTask;
23+
}
24+
}
25+
/*
26+
$3476. 最大化任务分配的利润
27+
https://leetcode.cn/problems/maximize-profit-from-task-assignment/description/
28+
29+
给定一个整数数组 workers,其中 workers[i] 表示第 i 个工人的技能等级。同时给定一个 2 维数组 tasks,其中:
30+
- tasks[i][0] 表示完成任务所需的技能要求。
31+
- tasks[i][1] 表示完成任务的收益。
32+
每一个工人 最多 能完成一个任务,并且只有在他们的技能等级 等于 任务的技能要求时才能获取此任务。今天又有一名 额外 工人加入,他可以承接任何任务,无论 技能要求如何。
33+
返回按照最优方式分配任务给工人所能获得的 最大 总利润。
34+
提示:
35+
1 <= workers.length <= 10^5
36+
1 <= workers[i] <= 10^9
37+
1 <= tasks.length <= 10^5
38+
tasks[i].length == 2
39+
1 <= tasks[i][0], tasks[i][1] <= 10^9
40+
41+
分组 + 贪心。
42+
时间复杂度 O(nlogn)。
43+
*/
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import java.util.HashMap;
2+
import java.util.List;
3+
import java.util.Map;
4+
5+
public class SolutionP3481 {
6+
private Map<Character, String> replace;
7+
private Map<String, String> memo;
8+
9+
public String applySubstitutions(List<List<String>> replacements, String text) {
10+
replace = new HashMap<>();
11+
for (List<String> re : replacements) {
12+
replace.put(re.get(0).charAt(0), re.get(1));
13+
}
14+
memo = new HashMap<>();
15+
return dfs(text);
16+
}
17+
18+
private String dfs(String s) {
19+
if (memo.containsKey(s)) return memo.get(s);
20+
StringBuilder sb = new StringBuilder();
21+
int i = 0, n = s.length();
22+
while (i < n) {
23+
if (s.charAt(i) != '%') {
24+
sb.append(s.charAt(i));
25+
i += 1;
26+
} else {
27+
sb.append(dfs(replace.get(s.charAt(i + 1))));
28+
i += 3;
29+
}
30+
}
31+
String res = sb.toString();
32+
memo.put(s, res);
33+
return res;
34+
}
35+
}
36+
/*
37+
$3481. 应用替换
38+
https://leetcode.cn/problems/apply-substitutions/description/
39+
40+
给定一个 replacements 映射和一个可能包含格式为 %var% 占位符 的字符串 text,其中每个 var 对应 replacements 中的一个键。每个替换值本身可能包含 一个或多个 此类占位符。每个 占位符 都被与其相应的替换键对应的值替换。
41+
返回完全替换后 不 含任何 占位符 的 text 字符串。
42+
提示:
43+
1 <= replacements.length <= 10
44+
replacements 中的每个元素是一个双值列表 [key, value],其中:
45+
key 是一个大写英语字母。
46+
value 是一个最多有 8 个字符,可能包含 0 个或更多格式为 %<key>% 的占位符的非空字符串。
47+
所有的替换键互不相同。
48+
text 字符串是通过从替换映射中随机串联所有 key 占位符(格式为 %<key>%)而形成的,以虚线分隔。
49+
text.length == 4 * replacements.length - 1
50+
text 或任何替换值中的每个占位符对应 replacements 映射中的一个键。
51+
替换键之间没有循环依赖。
52+
53+
记忆化搜索。
54+
https://leetcode.cn/problems/apply-substitutions/solutions/3680990/ji-yi-hua-sou-suo-by-endlesscheng-kn4j/
55+
时间复杂度:O(L * 2^n)。其中 L <= 8。
56+
*/
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import java.util.Arrays;
2+
3+
public class SolutionP3491 {
4+
public boolean phonePrefix(String[] numbers) {
5+
int n = numbers.length;
6+
Arrays.sort(numbers);
7+
for (int i = 1; i < n; i++) {
8+
if (numbers[i].startsWith(numbers[i - 1])) {
9+
return false;
10+
}
11+
}
12+
return true;
13+
}
14+
}
15+
/*
16+
$3491. 电话号码前缀
17+
https://leetcode.cn/problems/phone-number-prefix/description/
18+
19+
给定一个字符串数组 numbers 表示电话号码。如果没有电话号码是任何其他电话号码的前缀,则返回 true;否则,返回 false。
20+
提示:
21+
2 <= numbers.length <= 50
22+
1 <= numbers[i].length <= 50
23+
所有数字只包含 '0' 到 '9' 的数位。
24+
25+
排序后一定相邻。
26+
时间复杂度 O(nlogn * L)。
27+
*/
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
public class SolutionP3496 {
2+
public int maxScore(int[] nums) {
3+
int n = nums.length;
4+
int sum = nums[0], minSingle = nums[0], minPair = Integer.MAX_VALUE; // 奇数长度剩下一个, 偶数长度剩下相邻的一对
5+
for (int i = 1; i < n; i++) {
6+
sum += nums[i];
7+
minSingle = Math.min(minSingle, nums[i]);
8+
minPair = Math.min(minPair, nums[i] + nums[i - 1]);
9+
}
10+
if (n % 2 == 1) return sum - minSingle;
11+
return sum - minPair;
12+
}
13+
}
14+
/*
15+
$3496. 最大化配对删除后的得分
16+
https://leetcode.cn/problems/maximize-score-after-pair-deletions/description/
17+
18+
给定一个整数数组 nums。当数组中元素超过两个时,你 必须 重复执行以下操作中的一个:
19+
- 删除最前面的两个元素。
20+
- 删除最后面的两个元素。
21+
- 删除第一和最后一个元素。
22+
对于每次操作,将移除的元素之和加到你的总分上。
23+
返回你可以达到的 最高 分数。
24+
提示:
25+
1 <= nums.length <= 10^5
26+
-10^4 <= nums[i] <= 10^4
27+
28+
脑筋急转弯。
29+
奇数长度剩下一个, 偶数长度剩下相邻的一对
30+
时间复杂度 O(n)。
31+
*/
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class SolutionP3476Tests {
5+
private final SolutionP3476 solutionP3476 = new SolutionP3476();
6+
7+
@Test
8+
public void example1() {
9+
int[] workers = {1, 2, 3, 4, 5};
10+
int[][] tasks = UtUtils.stringToInts2("[[1,100],[2,400],[3,100],[3,400]]");
11+
long expected = 1000;
12+
Assertions.assertEquals(expected, solutionP3476.maxProfit(workers, tasks));
13+
}
14+
15+
@Test
16+
public void example2() {
17+
int[] workers = {10, 10000, 100000000};
18+
int[][] tasks = UtUtils.stringToInts2("[[1,100]]");
19+
long expected = 100;
20+
Assertions.assertEquals(expected, solutionP3476.maxProfit(workers, tasks));
21+
}
22+
23+
@Test
24+
public void example3() {
25+
int[] workers = {7};
26+
int[][] tasks = UtUtils.stringToInts2("[[3,3],[3,3]]");
27+
long expected = 3;
28+
Assertions.assertEquals(expected, solutionP3476.maxProfit(workers, tasks));
29+
}
30+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
import java.util.List;
5+
6+
public class SolutionP3481Tests {
7+
private final SolutionP3481 solutionP3481 = new SolutionP3481();
8+
9+
@Test
10+
public void example1() {
11+
List<List<String>> replacements = UtUtils.stringToStringList2("""
12+
[["A","abc"],["B","def"]]
13+
""");
14+
String text = "%A%_%B%";
15+
String expected = "abc_def";
16+
Assertions.assertEquals(expected, solutionP3481.applySubstitutions(replacements, text));
17+
}
18+
19+
@Test
20+
public void example2() {
21+
List<List<String>> replacements = UtUtils.stringToStringList2("""
22+
[["A","bce"],["B","ace"],["C","abc%B%"]]
23+
""");
24+
String text = "%A%_%B%_%C%";
25+
String expected = "bce_ace_abcace";
26+
Assertions.assertEquals(expected, solutionP3481.applySubstitutions(replacements, text));
27+
}
28+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class SolutionP3491Tests {
5+
private final SolutionP3491 solutionP3491 = new SolutionP3491();
6+
7+
@Test
8+
public void example1() {
9+
String[] numbers = {"1", "2", "4", "3"};
10+
Assertions.assertTrue(solutionP3491.phonePrefix(numbers));
11+
}
12+
13+
@Test
14+
public void example2() {
15+
String[] numbers = {"001", "007", "15", "00153"};
16+
Assertions.assertFalse(solutionP3491.phonePrefix(numbers));
17+
}
18+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class SolutionP3496Tests {
5+
private final SolutionP3496 solutionP3496 = new SolutionP3496();
6+
7+
@Test
8+
public void example1() {
9+
int[] nums = {2, 4, 1};
10+
int expected = 6;
11+
Assertions.assertEquals(expected, solutionP3496.maxScore(nums));
12+
}
13+
14+
@Test
15+
public void example2() {
16+
int[] nums = {5, -1, 4, 2};
17+
int expected = 7;
18+
Assertions.assertEquals(expected, solutionP3496.maxScore(nums));
19+
}
20+
}

leetcode/leetcode-35/src/test/resources/solution3416-example4-input.txt

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import java.util.PriorityQueue;
2+
3+
public class SolutionP3506 {
4+
public long minEliminationTime(int[] timeReq, int splitTime) {
5+
PriorityQueue<Long> pq = new PriorityQueue<>();
6+
for (long time : timeReq) {
7+
pq.add(time);
8+
}
9+
while (pq.size() > 1) {
10+
pq.remove();
11+
long secondMin = pq.remove();
12+
pq.offer(secondMin + splitTime);
13+
}
14+
return pq.remove();
15+
}
16+
}
17+
/*
18+
$3506. 查找消除细菌菌株所需时间
19+
https://leetcode.cn/problems/find-time-required-to-eliminate-bacterial-strains/description/
20+
21+
给定一个整数数组 timeReq 和一个整数 splitTime。
22+
在人体微观世界中,免疫系统面临着一项非凡的挑战:对抗快速繁殖的细菌群落,这对身体的生存构成威胁。
23+
最初,只部署一个 白细胞(WBC)来消除细菌。然而,单独的白细胞很快意识到它无法跟上细菌的生长速度。
24+
WBC制定了一种巧妙的策略来对抗细菌:
25+
- 第 i 个细菌菌株需要 timeReq[i] 个时间单位来被消除。
26+
- 单个白细胞只能消除 一个 细菌菌株。之后,白细胞耗尽,无法执行任何其他任务。
27+
- 一个白细胞可以将自身分裂为两个白细胞,但这需要 splitTime 单位时间。一旦分裂,两个白细胞就可以 并行 消灭细菌。
28+
- 一个白细胞仅可以攻击一个细菌菌株。多个白细胞不能同时攻击一个菌株。
29+
您必须确定消除所有细菌菌株所需的 最短 时间。
30+
注意,细菌菌株可以按任何顺序消除。
31+
提示:
32+
2 <= timeReq.length <= 10^5
33+
1 <= timeReq[i] <= 10^9
34+
1 <= splitTime <= 10^9
35+
36+
相似题目: $1199. 建造街区的最短时间
37+
https://leetcode.cn/problems/minimum-time-to-build-blocks/
38+
*/

0 commit comments

Comments
 (0)