Skip to content

Commit b5aea92

Browse files
committed
第146场双周赛T1~T4 (4)
1 parent 76616f6 commit b5aea92

File tree

8 files changed

+302
-0
lines changed

8 files changed

+302
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
public class Solution3392 {
2+
public int countSubarrays(int[] nums) {
3+
int n = nums.length;
4+
int ans = 0;
5+
for (int i = 1; i + 1 < n; i++) {
6+
if ((nums[i - 1] + nums[i + 1]) * 2 == nums[i]) {
7+
ans++;
8+
}
9+
}
10+
return ans;
11+
}
12+
}
13+
/*
14+
3392. 统计符合条件长度为 3 的子数组数目
15+
https://leetcode.cn/problems/count-subarrays-of-length-three-with-a-condition/description/
16+
17+
第 146 场双周赛 T1。
18+
19+
给你一个整数数组 nums ,请你返回长度为 3 的 子数组,满足第一个数和第三个数的和恰好为第二个数的一半。
20+
子数组 指的是一个数组中连续 非空 的元素序列。
21+
提示:
22+
3 <= nums.length <= 100
23+
-100 <= nums[i] <= 100
24+
25+
模拟。
26+
时间复杂度 O(n)。
27+
*/
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
public class Solution3393 {
2+
private static final int MOD = (int) (1e9 + 7);
3+
4+
public int countPathsWithXorValue(int[][] grid, int k) {
5+
int m = grid.length;
6+
int n = grid[0].length;
7+
8+
// 15 xor 16 = 31
9+
long[][][] f = new long[m][n][17];
10+
f[0][0][grid[0][0]] = 1;
11+
for (int i = 0; i < m; i++) {
12+
for (int j = 0; j < n; j++) {
13+
for (int k0 = 0; k0 < 17; k0++) {
14+
int k1 = k0 ^ grid[i][j];
15+
if (k1 > 16) continue;
16+
if (j - 1 >= 0) {
17+
f[i][j][k1] += f[i][j - 1][k0];
18+
}
19+
if (i - 1 >= 0) {
20+
f[i][j][k1] += f[i - 1][j][k0];
21+
}
22+
f[i][j][k1] %= MOD;
23+
}
24+
}
25+
}
26+
return (int) f[m - 1][n - 1][k];
27+
}
28+
}
29+
/*
30+
3393. 统计异或值为给定值的路径数目
31+
https://leetcode.cn/problems/count-paths-with-the-given-xor-value/description/
32+
33+
第 146 场双周赛 T2。
34+
35+
给你一个大小为 m x n 的二维整数数组 grid 和一个整数 k 。
36+
你的任务是统计满足以下 条件 且从左上格子 (0, 0) 出发到达右下格子 (m - 1, n - 1) 的路径数目:
37+
- 每一步你可以向右或者向下走,也就是如果格子存在的话,可以从格子 (i, j) 走到格子 (i, j + 1) 或者格子 (i + 1, j) 。
38+
- 路径上经过的所有数字 XOR 异或值必须 等于 k 。
39+
请你返回满足上述条件的路径总数。
40+
由于答案可能很大,请你将答案对 10^9 + 7 取余 后返回。
41+
提示:
42+
1 <= m == grid.length <= 300
43+
1 <= n == grid[r].length <= 300
44+
0 <= grid[r][c] < 16
45+
0 <= k < 16
46+
47+
动态规划。
48+
时间复杂度 O(mnk)。
49+
相似题目: 2435. 矩阵中和能被 K 整除的路径
50+
https://leetcode.cn/problems/paths-in-matrix-whose-sum-is-divisible-by-k/
51+
*/
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import java.util.ArrayList;
2+
import java.util.Comparator;
3+
import java.util.List;
4+
5+
public class Solution3394 {
6+
public boolean checkValidCuts(int n, int[][] rectangles) {
7+
return check(rectangles, 0) || check(rectangles, 1);
8+
}
9+
10+
// op:0 x坐标 op:1 y坐标
11+
private boolean check(int[][] rectangles, int op) {
12+
List<int[]> intervals = new ArrayList<>();
13+
for (int[] p : rectangles) intervals.add(new int[]{p[op], p[op + 2]});
14+
intervals.sort(Comparator.comparingInt(o -> o[0]));
15+
List<int[]> ans = new ArrayList<>();
16+
for (int[] p : intervals) {
17+
int l = p[0], r = p[1] - 1;
18+
if (!ans.isEmpty() && l <= ans.getLast()[1]) {
19+
ans.getLast()[1] = Math.max(ans.getLast()[1], r);
20+
} else {
21+
ans.add(new int[]{l, r});
22+
}
23+
}
24+
return ans.size() >= 3;
25+
}
26+
}
27+
/*
28+
3394. 判断网格图能否被切割成块
29+
https://leetcode.cn/problems/check-if-grid-can-be-cut-into-sections/description/
30+
31+
第 146 场双周赛 T3。
32+
33+
给你一个整数 n 表示一个 n x n 的网格图,坐标原点是这个网格图的左下角。同时给你一个二维坐标数组 rectangles ,其中 rectangles[i] 的格式为 [startx, starty, endx, endy] ,表示网格图中的一个矩形。每个矩形定义如下:
34+
- (startx, starty):矩形的左下角。
35+
- (endx, endy):矩形的右上角。
36+
注意 ,矩形相互之间不会重叠。你的任务是判断是否能找到两条 要么都垂直要么都水平 的 两条切割线 ,满足:
37+
- 切割得到的三个部分分别都 至少 包含一个矩形。
38+
- 每个矩形都 恰好仅 属于一个切割得到的部分。
39+
如果可以得到这样的切割,请你返回 true ,否则返回 false 。
40+
提示:
41+
3 <= n <= 10^9
42+
3 <= rectangles.length <= 10^5
43+
0 <= rectangles[i][0] < rectangles[i][2] <= n
44+
0 <= rectangles[i][1] < rectangles[i][3] <= n
45+
矩形之间两两不会有重叠。
46+
47+
相似题目: 56. 合并区间
48+
https://leetcode.cn/problems/merge-intervals/
49+
*/
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import java.util.HashMap;
2+
import java.util.Map;
3+
4+
public class Solution3395 {
5+
static final int MOD = (int) (1e9 + 7);
6+
7+
public int subsequencesWithMiddleMode(int[] nums) {
8+
int n = nums.length;
9+
long ans = (long) n * (n - 1) * (n - 2) * (n - 3) * (n - 4) / 120; // 所有方案数
10+
Map<Integer, Integer> suf = new HashMap<>();
11+
for (int x : nums) {
12+
suf.merge(x, 1, Integer::sum); // suf[x]++
13+
}
14+
Map<Integer, Integer> pre = new HashMap<>(suf.size()); // 预分配空间
15+
// 枚举 x,作为子序列正中间的数
16+
for (int left = 0; left < n - 2; left++) {
17+
int x = nums[left];
18+
suf.merge(x, -1, Integer::sum); // suf[x]--
19+
if (left > 1) {
20+
int right = n - 1 - left;
21+
int preX = pre.getOrDefault(x, 0);
22+
int sufX = suf.get(x);
23+
// 不合法:只有一个 x
24+
ans -= (long) comb2(left - preX) * comb2(right - sufX);
25+
// 不合法:只有两个 x,且至少有两个 y(y != x)
26+
for (Map.Entry<Integer, Integer> e : suf.entrySet()) {
27+
int y = e.getKey();
28+
if (y == x) {
29+
continue;
30+
}
31+
int sufY = e.getValue(); // 注意 sufY 可能是 0
32+
int preY = pre.getOrDefault(y, 0);
33+
// 左边有两个 y,右边有一个 x,即 yy x xz(z 可以等于 y)
34+
ans -= (long) comb2(preY) * sufX * (right - sufX);
35+
// 右边有两个 y,左边有一个 x,即 zx x yy(z 可以等于 y)
36+
ans -= (long) comb2(sufY) * preX * (left - preX);
37+
// 左右各有一个 y,另一个 x 在左边,即 xy x yz(z != y)
38+
ans -= (long) preY * sufY * preX * (right - sufX - sufY);
39+
// 左右各有一个 y,另一个 x 在右边,即 zy x xy(z != y)
40+
ans -= (long) preY * sufY * sufX * (left - preX - preY);
41+
}
42+
}
43+
pre.merge(x, 1, Integer::sum); // pre[x]++
44+
}
45+
return (int) (ans % MOD);
46+
}
47+
48+
private int comb2(int num) {
49+
return num * (num - 1) / 2;
50+
}
51+
}
52+
/*
53+
3395. 唯一中间众数子序列 I
54+
https://leetcode.cn/problems/subsequences-with-a-unique-middle-mode-i/description/
55+
56+
第 146 场双周赛 T4。
57+
58+
给你一个整数数组 nums ,请你求出 nums 中大小为 5 的 子序列 的数目,它是 唯一中间众数序列 。
59+
由于答案可能很大,请你将答案对 10^9 + 7 取余 后返回。
60+
众数 指的是一个数字序列中出现次数 最多 的元素。
61+
如果一个数字序列众数只有一个,我们称这个序列有 唯一众数 。
62+
一个大小为 5 的数字序列 seq ,如果它中间的数字(seq[2])是唯一众数,那么称它是 唯一中间众数 序列。
63+
提示:
64+
5 <= nums.length <= 1000
65+
-10^9 <= nums[i] <= 10^9
66+
67+
枚举。
68+
时间复杂度 O(n^2)
69+
https://leetcode.cn/problems/subsequences-with-a-unique-middle-mode-i/solutions/3026877/zheng-nan-ze-fan-fen-lei-tao-lun-qian-ho-f7cd/
70+
rating 2818 (clist.by)
71+
*/
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 Solution3392Tests {
5+
private final Solution3392 solution3392 = new Solution3392();
6+
7+
@Test
8+
public void example1() {
9+
int[] nums = {1, 2, 1, 4, 1};
10+
int expected = 1;
11+
Assertions.assertEquals(expected, solution3392.countSubarrays(nums));
12+
}
13+
14+
@Test
15+
public void example2() {
16+
int[] nums = {1, 1, 1};
17+
int expected = 0;
18+
Assertions.assertEquals(expected, solution3392.countSubarrays(nums));
19+
}
20+
}
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 Solution3393Tests {
5+
private final Solution3393 solution3393 = new Solution3393();
6+
7+
@Test
8+
public void example1() {
9+
int[][] grid = UtUtils.stringToInts2("[[2, 1, 5], [7, 10, 0], [12, 6, 4]]");
10+
int k = 11;
11+
int expected = 3;
12+
Assertions.assertEquals(expected, solution3393.countPathsWithXorValue(grid, k));
13+
}
14+
15+
@Test
16+
public void example2() {
17+
int[][] grid = UtUtils.stringToInts2("[[1, 3, 3, 3], [0, 3, 3, 2], [3, 0, 1, 1]]");
18+
int k = 2;
19+
int expected = 5;
20+
Assertions.assertEquals(expected, solution3393.countPathsWithXorValue(grid, k));
21+
}
22+
23+
@Test
24+
public void example3() {
25+
int[][] grid = UtUtils.stringToInts2("[[1, 1, 1, 2], [3, 0, 3, 2], [3, 0, 2, 2]]");
26+
int k = 10;
27+
int expected = 0;
28+
Assertions.assertEquals(expected, solution3393.countPathsWithXorValue(grid, k));
29+
}
30+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution3394Tests {
5+
private final Solution3394 solution3394 = new Solution3394();
6+
7+
@Test
8+
public void example1() {
9+
int n = 5;
10+
int[][] rectangles = UtUtils.stringToInts2("[[1,0,5,2],[0,2,2,4],[3,2,5,3],[0,4,4,5]]");
11+
Assertions.assertTrue(solution3394.checkValidCuts(n, rectangles));
12+
}
13+
14+
@Test
15+
public void example2() {
16+
int n = 4;
17+
int[][] rectangles = UtUtils.stringToInts2("[[0,0,1,1],[2,0,3,4],[0,2,2,3],[3,0,4,3]]");
18+
Assertions.assertTrue(solution3394.checkValidCuts(n, rectangles));
19+
}
20+
21+
@Test
22+
public void example3() {
23+
int n = 4;
24+
int[][] rectangles = UtUtils.stringToInts2("[[0,2,2,4],[1,0,3,2],[2,2,3,4],[3,0,4,2],[3,2,4,4]]");
25+
Assertions.assertFalse(solution3394.checkValidCuts(n, rectangles));
26+
}
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution3395Tests {
5+
private final Solution3395 solution3395 = new Solution3395();
6+
7+
@Test
8+
public void example1() {
9+
int[] nums = {1, 1, 1, 1, 1, 1};
10+
int expected = 6;
11+
Assertions.assertEquals(expected, solution3395.subsequencesWithMiddleMode(nums));
12+
}
13+
14+
@Test
15+
public void example2() {
16+
int[] nums = {1, 2, 2, 3, 3, 4};
17+
int expected = 4;
18+
Assertions.assertEquals(expected, solution3395.subsequencesWithMiddleMode(nums));
19+
}
20+
21+
@Test
22+
public void example3() {
23+
int[] nums = {0, 1, 2, 3, 4, 5, 6, 7, 8};
24+
int expected = 0;
25+
Assertions.assertEquals(expected, solution3395.subsequencesWithMiddleMode(nums));
26+
}
27+
}

0 commit comments

Comments
 (0)