Skip to content

Commit df3a697

Browse files
committed
1210-1477 (2)
1 parent 9ba73cf commit df3a697

File tree

5 files changed

+193
-8
lines changed

5 files changed

+193
-8
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import java.util.LinkedList;
2+
import java.util.Queue;
3+
4+
public class Solution1210 {
5+
private static final int[][] DIRS = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
6+
7+
public int minimumMoves(int[][] grid) {
8+
int n = grid.length;
9+
boolean[][][] visited = new boolean[n][n][2];
10+
Queue<int[]> queue = new LinkedList<>();
11+
visited[0][0][0] = true;
12+
queue.add(new int[]{0, 0, 0});
13+
int step = 0;
14+
while (!queue.isEmpty()) {
15+
int size = queue.size();
16+
for (int i = 0; i < size; i++) {
17+
int[] cur = queue.remove();
18+
if (cur[0] == n - 1 && cur[1] == n - 2) {
19+
return step;
20+
}
21+
for (int[] dir : DIRS) {
22+
int x = cur[0] + dir[0];
23+
int y = cur[1] + dir[1];
24+
int s = cur[2] ^ dir[2];
25+
int x2 = x + s;
26+
int y2 = y + (s ^ 1);
27+
if (x2 < n && y2 < n && !visited[x][y][s]
28+
&& grid[x][y] == 0 && grid[x2][y2] == 0
29+
&& (dir[2] == 0 || grid[x + 1][y + 1] == 0)) {
30+
visited[x][y][s] = true;
31+
queue.add(new int[]{x, y, s});
32+
}
33+
}
34+
}
35+
step++;
36+
}
37+
return -1;
38+
}
39+
}
40+
/*
41+
1210. 穿过迷宫的最少移动次数
42+
https://leetcode.cn/problems/minimum-moves-to-reach-target-with-rotations/
43+
44+
你还记得那条风靡全球的贪吃蛇吗?
45+
我们在一个 n*n 的网格上构建了新的迷宫地图,蛇的长度为 2,也就是说它会占去两个单元格。蛇会从左上角((0, 0) 和 (0, 1))开始移动。我们用 0 表示空单元格,用 1 表示障碍物。蛇需要移动到迷宫的右下角((n-1, n-2) 和 (n-1, n-1))。
46+
每次移动,蛇可以这样走:
47+
- 如果没有障碍,则向右移动一个单元格。并仍然保持身体的水平/竖直状态。
48+
- 如果没有障碍,则向下移动一个单元格。并仍然保持身体的水平/竖直状态。
49+
- 如果它处于水平状态并且其下面的两个单元都是空的,就顺时针旋转 90 度。蛇从((r, c)、(r, c+1))移动到 ((r, c)、(r+1, c))。
50+
- 如果它处于竖直状态并且其右面的两个单元都是空的,就逆时针旋转 90 度。蛇从((r, c)、(r+1, c))移动到((r, c)、(r, c+1))。
51+
返回蛇抵达目的地所需的最少移动次数。
52+
如果无法到达目的地,请返回 -1。
53+
提示:
54+
2 <= n <= 100
55+
0 <= grid[i][j] <= 1
56+
蛇保证从空单元格开始出发。
57+
58+
https://leetcode.cn/problems/minimum-moves-to-reach-target-with-rotations/solution/huan-zai-if-elseyi-ge-xun-huan-chu-li-li-tw8b/
59+
时间复杂度 O(n^2)
60+
空间复杂度 O(n^2)
61+
*/
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution1210Tests {
5+
private final Solution1210 solution1210 = new Solution1210();
6+
7+
@Test
8+
public void example1() {
9+
int[][] grid = UtUtils.stringToInts2("""
10+
[[0,0,0,0,0,1],
11+
[1,1,0,0,1,0],
12+
[0,0,0,0,1,1],
13+
[0,0,1,0,1,0],
14+
[0,1,1,0,0,0],
15+
[0,1,1,0,0,0]]
16+
""");
17+
int expected = 11;
18+
Assertions.assertEquals(expected, solution1210.minimumMoves(grid));
19+
}
20+
21+
@Test
22+
public void example2() {
23+
int[][] grid = UtUtils.stringToInts2("""
24+
[[0,0,1,1,1,1],
25+
[0,0,0,0,1,1],
26+
[1,1,0,0,0,1],
27+
[1,1,1,0,0,1],
28+
[1,1,1,0,0,1],
29+
[1,1,1,0,0,0]]
30+
""");
31+
int expected = 9;
32+
Assertions.assertEquals(expected, solution1210.minimumMoves(grid));
33+
}
34+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
public class Solution1477 {
2+
public int minSumOfLengths(int[] arr, int target) {
3+
int n = arr.length;
4+
5+
// f[i] 表示 [0, i) 之间最短的和为 target 的子数组长度
6+
int[] f = new int[n + 1];
7+
f[0] = n + 1;
8+
9+
int left = 0, right = 0;
10+
int sum = 0;
11+
int min = n + 1;
12+
while (right < n) {
13+
sum += arr[right];
14+
while (sum > target) {
15+
sum -= arr[left];
16+
left++;
17+
}
18+
if (sum == target) {
19+
min = Math.min(min, (right - left + 1) + f[left]);
20+
f[right + 1] = Math.min(f[right], right - left + 1);
21+
} else {
22+
f[right + 1] = f[right];
23+
}
24+
right++;
25+
}
26+
return (min == n + 1) ? -1 : min;
27+
}
28+
}
29+
/*
30+
1477. 找两个和为目标值且不重叠的子数组
31+
https://leetcode.cn/problems/find-two-non-overlapping-sub-arrays-each-with-target-sum/
32+
33+
给你一个整数数组 arr 和一个整数值 target 。
34+
请你在 arr 中找 两个互不重叠的子数组 且它们的和都等于 target 。可能会有多种方案,请你返回满足要求的两个子数组长度和的 最小值 。
35+
请返回满足要求的最小长度和,如果无法找到这样的两个子数组,请返回 -1 。
36+
提示:
37+
1 <= arr.length <= 10^5
38+
1 <= arr[i] <= 1000
39+
1 <= target <= 10^8
40+
41+
双指针 + 动态规划
42+
时间复杂度 O(n)
43+
*/
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution1477Tests {
5+
private final Solution1477 solution1477 = new Solution1477();
6+
7+
@Test
8+
public void example1() {
9+
int[] arr = {3, 2, 2, 4, 3};
10+
int target = 3;
11+
int expected = 2;
12+
Assertions.assertEquals(expected, solution1477.minSumOfLengths(arr, target));
13+
}
14+
15+
@Test
16+
public void example2() {
17+
int[] arr = {7, 3, 4, 7};
18+
int target = 7;
19+
int expected = 2;
20+
Assertions.assertEquals(expected, solution1477.minSumOfLengths(arr, target));
21+
}
22+
23+
@Test
24+
public void example3() {
25+
int[] arr = {4, 3, 2, 6, 2, 3, 4};
26+
int target = 6;
27+
int expected = -1;
28+
Assertions.assertEquals(expected, solution1477.minSumOfLengths(arr, target));
29+
}
30+
31+
@Test
32+
public void example4() {
33+
int[] arr = {5, 5, 4, 4, 5};
34+
int target = 3;
35+
int expected = -1;
36+
Assertions.assertEquals(expected, solution1477.minSumOfLengths(arr, target));
37+
}
38+
39+
@Test
40+
public void example5() {
41+
int[] arr = {3, 1, 1, 1, 5, 1, 2, 1};
42+
int target = 3;
43+
int expected = 3;
44+
Assertions.assertEquals(expected, solution1477.minSumOfLengths(arr, target));
45+
}
46+
}

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
public class Solution6331 {
22
public int maximizeWin(int[] prizePositions, int k) {
3-
int len = prizePositions.length;
4-
int left = 0;
5-
int right = 0;
6-
// pre[right] = max{[l, right]}
7-
int[] pre = new int[len + 1];
3+
int n = prizePositions.length;
4+
5+
// f[i] 表示 [0, i) 线段长度 <= k 的最多奖品数
6+
int[] f = new int[n + 1];
7+
8+
int left = 0, right = 0;
89
int res = 0;
9-
while (right < len) {
10+
while (right < n) {
1011
while (prizePositions[right] - prizePositions[left] > k) {
1112
left++;
1213
}
13-
res = Math.max(res, right - left + 1 + pre[left]);
14-
pre[right + 1] = Math.max(pre[right], right - left + 1);
14+
res = Math.max(res, (right - left + 1) + f[left]);
15+
f[right + 1] = Math.max(f[right], right - left + 1);
1516
right++;
1617
}
1718
return res;

0 commit comments

Comments
 (0)