Skip to content

Commit 423f44e

Browse files
committed
2547 & 第330场周赛T1~T4 & 第97场双周赛T1~T4 & 第331场周赛T1~T4 (13)
1 parent d1c27a4 commit 423f44e

34 files changed

+951
-105
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,8 @@ Hierholzer 算法
619619
- ~~[哈工大 OJ](http://acm.hit.edu.cn/)~~
620620
- [洛谷](https://www.luogu.com.cn/)
621621
- [excalidraw](https://excalidraw.com/)
622-
- [leetcode-rating-predictor](http://lcpredictor.herokuapp.com/) | [github](https://github.com/SysSn13/leetcode-rating-predictor) | [onrender](http://lcpredictor.onrender.com/)
622+
- [leetcode-rating-predictor](https://lcpredictor.onrender.com/) | [github](https://github.com/SysSn13/leetcode-rating-predictor)
623+
- [lccn.lbao.site](https://lccn.lbao.site/)
623624
- [zerotrac-leetcode_problem_rating](https://zerotrac.github.io/leetcode_problem_rating/)
624625
- [clist.by](https://clist.by/account/zhang-yi-yang/resource/leetcode.com/)
625626
- [visualgo](https://visualgo.net/zh)

leetcode-01/src/main/java/Solution76.java

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,45 @@
22
import java.util.Map;
33

44
public class Solution76 {
5+
private Map<Character, Integer> tMap;
6+
57
public String minWindow(String s, String t) {
6-
if (s.length() < t.length()) {
8+
int n = s.length();
9+
int m = t.length();
10+
if (n < m) {
711
return "";
812
}
9-
Map<Character, Integer> sCntMap = new HashMap<>();
10-
Map<Character, Integer> tCntMap = new HashMap<>();
13+
tMap = new HashMap<>();
1114
for (char ch : t.toCharArray()) {
12-
tCntMap.put(ch, tCntMap.getOrDefault(ch, 0) + 1);
15+
tMap.put(ch, tMap.getOrDefault(ch, 0) + 1);
1316
}
1417

15-
// 双指针-滑动窗口
16-
int left = 0;
17-
int right = 0;
18-
// 此处有坑,不能直接 s.length() 因为存在 s = "a", t = "b" 用例
19-
int ansLen = Integer.MAX_VALUE;
20-
int ansStart = 0;
21-
while (right < s.length()) {
22-
// 右指针右移 增加字符
23-
char addCh = s.charAt(right);
24-
sCntMap.put(addCh, sCntMap.getOrDefault(addCh, 0) + 1);
25-
right++;
26-
27-
// 左指针右移
28-
while (checkInclusion(sCntMap, tCntMap)) {
29-
int curLen = right - left;
30-
if (curLen < ansLen) {
31-
ansLen = curLen;
32-
ansStart = left;
18+
Map<Character, Integer> sMap = new HashMap<>();
19+
int left = 0, right = 0;
20+
int ansLen = n + 1;
21+
int ansL = 0;
22+
while (right < n) {
23+
char ch = s.charAt(right);
24+
sMap.put(ch, sMap.getOrDefault(ch, 0) + 1);
25+
while (check(sMap)) {
26+
if (ansLen > right - left + 1) {
27+
ansLen = right - left + 1;
28+
ansL = left;
3329
}
34-
// 移除字符
35-
char rmCh = s.charAt(left);
36-
sCntMap.put(rmCh, sCntMap.getOrDefault(rmCh, 0) - 1);
30+
char rm = s.charAt(left);
31+
sMap.put(rm, sMap.get(rm) - 1);
3732
left++;
3833
}
34+
right++;
3935
}
40-
return ansLen == Integer.MAX_VALUE ? "" : s.substring(ansStart, ansStart + ansLen);
36+
return (ansLen == n + 1) ? "" : s.substring(ansL, ansL + ansLen);
4137
}
4238

43-
// window 是否包含 need 的字符
44-
private boolean checkInclusion(Map<Character, Integer> window, Map<Character, Integer> need) {
45-
for (Map.Entry<Character, Integer> entry : need.entrySet()) {
46-
char curCh = entry.getKey();
47-
if (window.getOrDefault(curCh, 0) < entry.getValue()) {
39+
// sMap 是否完全覆盖 tMap
40+
private boolean check(Map<Character, Integer> sMap) {
41+
for (Map.Entry<Character, Integer> entry : tMap.entrySet()) {
42+
char ch = entry.getKey();
43+
if (sMap.getOrDefault(ch, 0) < entry.getValue()) {
4844
return false;
4945
}
5046
}

leetcode-03/src/main/java/Solution209.java

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,19 @@
11
public class Solution209 {
22
public int minSubArrayLen(int target, int[] nums) {
3-
// 双指针
4-
int left = 0;
5-
int right = 0;
3+
int n = nums.length;
4+
int left = 0, right = 0;
65
int sum = 0;
7-
int minLen = Integer.MAX_VALUE;
8-
while (right < nums.length) {
9-
// 右指针右移
6+
int min = n + 1;
7+
while (right < n) {
108
sum += nums[right];
11-
right++;
12-
139
while (sum >= target) {
14-
minLen = Math.min(minLen, right - left);
15-
16-
// 左指针右移
10+
min = Math.min(min, right - left + 1);
1711
sum -= nums[left];
1812
left++;
1913
}
14+
right++;
2015
}
21-
return (minLen == Integer.MAX_VALUE) ? 0 : minLen;
16+
return (min == n + 1) ? 0 : min;
2217
}
2318
}
2419
/*
Lines changed: 13 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,19 @@
1-
import java.math.BigInteger;
2-
31
public class Solution713 {
4-
/**
5-
* 类似 "前缀和" 的 "前缀积"
6-
* 时间复杂度 O(n^2) 使用 BigInteger 是因为 long 会溢出
7-
*/
8-
public int numSubarrayProductLessThanK2(int[] nums, int k) {
9-
// 前缀“积”
10-
int len = nums.length;
11-
BigInteger[] preSum = new BigInteger[len + 1];
12-
preSum[0] = new BigInteger("1");
13-
for (int i = 0; i < len; i++) {
14-
preSum[i + 1] = preSum[i].multiply(BigInteger.valueOf(nums[i]));
15-
}
16-
// 枚举连续子数组 时间复杂度 O(n^2)
17-
BigInteger kBigInteger = BigInteger.valueOf(k);
18-
int res = 0;
19-
for (int i = 0; i < len; i++) {
20-
for (int j = i; j < len; j++) {
21-
if (preSum[j + 1].divide(preSum[i]).compareTo(kBigInteger) < 0) {
22-
res++;
23-
}
24-
}
25-
}
26-
return res;
27-
}
28-
29-
// 双指针 时间复杂度 O(n)
302
public int numSubarrayProductLessThanK(int[] nums, int k) {
31-
// 双指针
32-
int left = 0;
33-
int right = 0;
34-
// 乘积
35-
long product = 1;
36-
int cnt = 0;
37-
while (right < nums.length) {
38-
// 右指针右移
3+
int n = nums.length;
4+
int left = 0, right = 0;
5+
long product = 1L;
6+
int res = 0;
7+
while (right < n) {
398
product *= nums[right];
40-
right++;
41-
// 左指针右移
42-
while (product >= k && left < right) {
9+
while (product >= k && left <= right) {
4310
product /= nums[left];
4411
left++;
4512
}
46-
cnt += right - left;
13+
res += right - left + 1;
14+
right++;
4715
}
48-
return cnt;
16+
return res;
4917
}
5018
}
5119
/*
@@ -59,8 +27,8 @@ public int numSubarrayProductLessThanK(int[] nums, int k) {
5927
1 <= nums[i] <= 1000
6028
0 <= k <= 10^6
6129
62-
参考第 560 题 https://leetcode.cn/problems/subarray-sum-equals-k/
63-
“前缀积” 时间复杂度 O(n^2)
64-
参考第 209 题 https://leetcode.cn/problems/minimum-size-subarray-sum/
65-
双指针 时间复杂度 O(n)
30+
双指针
31+
时间复杂度 O(n)
32+
相似题目: 209. 长度最小的子数组
33+
https://leetcode.cn/problems/minimum-size-subarray-sum/
6634
*/

leetcode-08/src/test/java/Solution713Tests.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ public void example1() {
1010
int k = 100;
1111
int expected = 8;
1212
Assertions.assertEquals(expected, solution713.numSubarrayProductLessThanK(nums, k));
13-
Assertions.assertEquals(expected, solution713.numSubarrayProductLessThanK2(nums, k));
1413
}
1514

1615
@Test
@@ -19,7 +18,6 @@ public void example2() {
1918
int k = 0;
2019
int expected = 0;
2120
Assertions.assertEquals(expected, solution713.numSubarrayProductLessThanK(nums, k));
22-
Assertions.assertEquals(expected, solution713.numSubarrayProductLessThanK2(nums, k));
2321
}
2422

2523
// 补充用例
@@ -29,6 +27,5 @@ public void example3() {
2927
int k = 9931;
3028
int expected = 4370;
3129
Assertions.assertEquals(expected, solution713.numSubarrayProductLessThanK(nums, k));
32-
// Assertions.assertEquals(expected, solution713.numSubarrayProductLessThanK2(nums, k));
3330
}
3431
}

leetcode-23/src/main/java/Solution2225.java

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import java.util.ArrayList;
2+
import java.util.Arrays;
23
import java.util.Collections;
34
import java.util.HashMap;
45
import java.util.HashSet;
@@ -9,25 +10,21 @@
910
public class Solution2225 {
1011
public List<List<Integer>> findWinners(int[][] matches) {
1112
Set<Integer> players = new HashSet<>();
12-
// 建图
13-
Map<Integer, Set<Integer>> inGraph = new HashMap<>();
13+
// 入度
14+
Map<Integer, Integer> deg = new HashMap<>();
1415
for (int[] match : matches) {
15-
int from = match[0];
16-
int to = match[1];
17-
players.add(from);
18-
players.add(to);
19-
20-
Set<Integer> inSet = inGraph.getOrDefault(to, new HashSet<>());
21-
inSet.add(from);
22-
inGraph.put(to, inSet);
16+
int u = match[0];
17+
int v = match[1];
18+
deg.put(v, deg.getOrDefault(v, 0) + 1);
19+
players.add(u);
20+
players.add(v);
2321
}
2422

2523
// 统计入度
2624
List<Integer> answer0 = new ArrayList<>();
2725
List<Integer> answer1 = new ArrayList<>();
2826
for (int player : players) {
29-
int inDegree = inGraph.getOrDefault(player, new HashSet<>()).size();
30-
27+
int inDegree = deg.getOrDefault(player, 0);
3128
if (inDegree == 0) {
3229
answer0.add(player);
3330
} else if (inDegree == 1) {
@@ -36,7 +33,7 @@ public List<List<Integer>> findWinners(int[][] matches) {
3633
}
3734
Collections.sort(answer0);
3835
Collections.sort(answer1);
39-
return List.of(answer0, answer1);
36+
return Arrays.asList(answer0, answer1);
4037
}
4138
}
4239
/*

leetcode-26/src/main/java/Solution2546.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ public boolean makeStringsEqual(String s, String target) {
1818
}
1919
return s0 != n && t0 != n;
2020
}
21+
22+
public boolean makeStringsEqual2(String s, String target) {
23+
return s.contains("1") == target.contains("1");
24+
}
2125
}
2226
/*
2327
2546. 执行逐位运算使字符串相等
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
public class Solution2547 {
2+
public int minCost(int[] nums, int k) {
3+
int n = nums.length;
4+
int[] g = new int[n + 1];
5+
for (int i = 0; i < n; i++) {
6+
int[] cnt = new int[n];
7+
int unique = 0;
8+
int min = Integer.MAX_VALUE;
9+
for (int j = i; j >= 0; j--) {
10+
int x = nums[j];
11+
if (cnt[x] == 0) {
12+
// 首次出现
13+
cnt[x] = 1;
14+
unique++;
15+
} else if (cnt[x] == 1) {
16+
// 非首次出现
17+
cnt[x] = 2;
18+
unique--;
19+
}
20+
min = Math.min(min, g[j] - unique);
21+
}
22+
g[i + 1] = k + min;
23+
}
24+
return g[n] + n;
25+
}
26+
}
27+
/*
28+
2547. 拆分数组的最小代价
29+
https://leetcode.cn/problems/minimum-cost-to-split-an-array/
30+
31+
第 329 场周赛 T4。
32+
33+
给你一个整数数组 nums 和一个整数 k 。
34+
将数组拆分成一些非空子数组。拆分的 代价 是每个子数组中的 重要性 之和。
35+
令 trimmed(subarray) 作为子数组的一个特征,其中所有仅出现一次的数字将会被移除。
36+
- 例如,trimmed([3,1,2,4,3,4]) = [3,4,3,4] 。
37+
子数组的 重要性 定义为 k + trimmed(subarray).length 。
38+
- 例如,如果一个子数组是 [1,2,3,3,3,4,4] ,trimmed([1,2,3,3,3,4,4]) = [3,3,3,4,4] 。这个子数组的重要性就是 k + 5 。
39+
找出并返回拆分 nums 的所有可行方案中的最小代价。
40+
子数组 是数组的一个连续 非空 元素序列。
41+
提示:
42+
1 <= nums.length <= 1000
43+
0 <= nums[i] < nums.length
44+
1 <= k <= 10^9
45+
46+
动态规划
47+
f[i] = min(k + cost(j,i) + f[j-1]) j in [0,i]
48+
f[i+1] = min(k + cost(j,i) + f[j])
49+
f[i+1] 表示划分 nums 前 i 个数的最小代价
50+
cost(j,i)
51+
子数组长度 - unique
52+
f[i+1] = min(k + i-j+1 - unique_j + f[j])
53+
f[i+1] = (i + 1) + k + min(f[j]-j - unique_j)
54+
g[i] = f[i] - i
55+
g[i+1] = k + min(g[j] - unique_j)
56+
f[n] = g[n] + n
57+
时间复杂度 O(n^2)
58+
*/
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
public class Solution2549 {
2+
public int distinctIntegers(int n) {
3+
return n == 1 ? 1 : n - 1;
4+
}
5+
}
6+
/*
7+
2549. 统计桌面上的不同数字
8+
https://leetcode.cn/problems/count-distinct-numbers-on-board/
9+
10+
第 330 场周赛 T1。
11+
12+
给你一个正整数 n ,开始时,它放在桌面上。在 10^9 天内,每天都要执行下述步骤:
13+
- 对于出现在桌面上的每个数字 x ,找出符合 1 <= i <= n 且满足 x % i == 1 的所有数字 i 。
14+
- 然后,将这些数字放在桌面上。
15+
返回在 10^9 天之后,出现在桌面上的 不同 整数的数目。
16+
注意:
17+
- 一旦数字放在桌面上,则会一直保留直到结束。
18+
- % 表示取余运算。例如,14 % 3 等于 2 。
19+
提示:
20+
1 <= n <= 100
21+
22+
2023农历新年后首场。工作日的周赛。
23+
观察规律,只有 n = 1 时,结果为 1,否则均为 n-1。
24+
*/

0 commit comments

Comments
 (0)