Skip to content

Commit b806e20

Browse files
committed
1138-1139-1237-1792 (4)
1 parent 104d574 commit b806e20

File tree

8 files changed

+277
-0
lines changed

8 files changed

+277
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
public class Solution1138 {
2+
public String alphabetBoardPath(String target) {
3+
int r = 0, c = 0;
4+
5+
StringBuilder stringBuilder = new StringBuilder();
6+
for (char ch : target.toCharArray()) {
7+
int nr = (ch - 'a') / 5;
8+
int nc = (ch - 'a') % 5;
9+
// 优先 向上走 向左走
10+
if (nr < r) {
11+
stringBuilder.append("U".repeat(r - nr));
12+
}
13+
if (nc < c) {
14+
stringBuilder.append("L".repeat(c - nc));
15+
}
16+
if (nr > r) {
17+
stringBuilder.append("D".repeat(nr - r));
18+
}
19+
if (nc > c) {
20+
stringBuilder.append("R".repeat(nc - c));
21+
}
22+
stringBuilder.append("!");
23+
r = nr;
24+
c = nc;
25+
}
26+
return stringBuilder.toString();
27+
}
28+
}
29+
/*
30+
1138. 字母板上的路径
31+
https://leetcode.cn/problems/alphabet-board-path/
32+
33+
我们从一块字母板上的位置 (0, 0) 出发,该坐标对应的字符为 board[0][0]。
34+
在本题里,字母板为board = ["abcde", "fghij", "klmno", "pqrst", "uvwxy", "z"],如下所示。
35+
我们可以按下面的指令规则行动:
36+
- 如果方格存在,'U' 意味着将我们的位置上移一行;
37+
- 如果方格存在,'D' 意味着将我们的位置下移一行;
38+
- 如果方格存在,'L' 意味着将我们的位置左移一列;
39+
- 如果方格存在,'R' 意味着将我们的位置右移一列;
40+
- '!' 会把在我们当前位置 (r, c) 的字符 board[r][c] 添加到答案中。
41+
(注意,字母板上只存在有字母的位置。)
42+
返回指令序列,用最小的行动次数让答案和目标 target 相同。你可以返回任何达成目标的路径。
43+
提示:
44+
1 <= target.length <= 100
45+
target 仅含有小写英文字母。
46+
47+
模拟。为了保证含有字符 'z' 时能够正常移动,每次移动时优先保证选择上移和左移。
48+
时间复杂度 O(n)
49+
空间复杂度 O(1)
50+
*/
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
public class Solution1139 {
2+
public int largest1BorderedSquare(int[][] grid) {
3+
int M = grid.length;
4+
int N = grid[0].length;
5+
int[][] up = new int[M + 1][N + 1];
6+
int[][] left = new int[M + 1][N + 1];
7+
int maxL = 0;
8+
for (int i = 1; i <= M; i++) {
9+
for (int j = 1; j <= N; j++) {
10+
if (grid[i - 1][j - 1] == 1) {
11+
up[i][j] = up[i - 1][j] + 1;
12+
left[i][j] = left[i][j - 1] + 1;
13+
int len = Math.min(up[i][j], left[i][j]);
14+
while (up[i][j - len + 1] < len || left[i - len + 1][j] < len) {
15+
len--;
16+
}
17+
maxL = Math.max(maxL, len);
18+
}
19+
}
20+
}
21+
return maxL * maxL;
22+
}
23+
}
24+
/*
25+
1139. 最大的以 1 为边界的正方形
26+
https://leetcode.cn/problems/largest-1-bordered-square/
27+
28+
给你一个由若干 0 和 1 组成的二维网格 grid,请你找出边界全部由 1 组成的最大 正方形 子网格,并返回该子网格中的元素数量。如果不存在,则返回 0。
29+
提示:
30+
1 <= grid.length <= 100
31+
1 <= grid[0].length <= 100
32+
grid[i][j] 为 0 或 1
33+
34+
动态规划
35+
left[x][y] 表示以 (x,y) 为起点左侧连续 1 的最大数目
36+
up[x][y] 表示以 (x,y) 为起点上侧连续 1 的最大数目
37+
时间复杂度 O(mn * min(m,n))
38+
时间复杂度 O(mn)
39+
*/
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 Solution1138Tests {
5+
private final Solution1138 solution1138 = new Solution1138();
6+
7+
@Test
8+
public void example1() {
9+
String target = "leet";
10+
String expected = "DDR!UURRR!!DDD!";
11+
Assertions.assertEquals(expected, solution1138.alphabetBoardPath(target));
12+
}
13+
14+
@Test
15+
public void example2() {
16+
String target = "code";
17+
String expected = "RR!DDRR!UUL!R!";
18+
Assertions.assertEquals(expected, solution1138.alphabetBoardPath(target));
19+
}
20+
}
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 Solution1139Tests {
5+
private final Solution1139 solution1139 = new Solution1139();
6+
7+
@Test
8+
public void example1() {
9+
int[][] grid = UtUtils.stringToInts2("[[1,1,1],[1,0,1],[1,1,1]]");
10+
int expected = 9;
11+
Assertions.assertEquals(expected, solution1139.largest1BorderedSquare(grid));
12+
}
13+
14+
@Test
15+
public void example2() {
16+
int[][] grid = UtUtils.stringToInts2("[[1,1,0,0]]");
17+
int expected = 1;
18+
Assertions.assertEquals(expected, solution1139.largest1BorderedSquare(grid));
19+
}
20+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import java.util.ArrayList;
2+
import java.util.List;
3+
4+
public class Solution1237 {
5+
public List<List<Integer>> findSolution(CustomFunction customfunction, int z) {
6+
List<List<Integer>> resList = new ArrayList<>();
7+
int y = 1000;
8+
for (int x = 1; x <= 1000; x++) {
9+
while (y >= 1 && customfunction.f(x, y) > z) {
10+
y--;
11+
}
12+
if (y >= 1 && customfunction.f(x, y) == z) {
13+
resList.add(List.of(x, y));
14+
}
15+
}
16+
return resList;
17+
}
18+
19+
static class CustomFunction {
20+
// Returns f(x, y) for any given positive integers x and y.
21+
// Note that f(x, y) is increasing with respect to both x and y.
22+
// i.e. f(x, y) < f(x + 1, y), f(x, y) < f(x, y + 1)
23+
public int f(int x, int y) {
24+
return x + y;
25+
}
26+
}
27+
}
28+
/*
29+
1237. 找出给定方程的正整数解
30+
https://leetcode.cn/problems/find-positive-integer-solution-for-a-given-equation/
31+
32+
给你一个函数 f(x, y) 和一个目标结果 z,函数公式未知,请你计算方程 f(x,y) == z 所有可能的正整数 数对 x 和 y。满足条件的结果数对可以按任意顺序返回。
33+
尽管函数的具体式子未知,但它是单调递增函数,也就是说:
34+
f(x, y) < f(x + 1, y)
35+
f(x, y) < f(x, y + 1)
36+
函数接口定义如下:
37+
```
38+
interface CustomFunction {
39+
public:
40+
// Returns some positive integer f(x, y) for two positive integers x and y based on a formula.
41+
int f(int x, int y);
42+
};
43+
```
44+
你的解决方案将按如下规则进行评判:
45+
- 判题程序有一个由 CustomFunction 的 9 种实现组成的列表,以及一种为特定的 z 生成所有有效数对的答案的方法。
46+
- 判题程序接受两个输入:function_id(决定使用哪种实现测试你的代码)以及目标结果 z 。
47+
- 判题程序将会调用你实现的 findSolution 并将你的结果与答案进行比较。
48+
- 如果你的结果与答案相符,那么解决方案将被视作正确答案,即 Accepted 。
49+
提示:
50+
1 <= function_id <= 9
51+
1 <= z <= 100
52+
题目保证 f(x, y) == z 的解处于 1 <= x, y <= 1000 的范围内。
53+
在 1 <= x, y <= 1000 的前提下,题目保证 f(x, y) 是一个 32 位有符号整数。
54+
55+
双指针。
56+
相似题目: 240. 搜索二维矩阵 II
57+
https://leetcode.cn/problems/search-a-2d-matrix-ii/
58+
*/
59+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
import java.util.List;
5+
6+
public class Solution1237Tests {
7+
private final Solution1237 solution1237 = new Solution1237();
8+
9+
@Test
10+
public void example1() {
11+
Solution1237.CustomFunction customfunction = new Solution1237.CustomFunction();
12+
int z = 5;
13+
List<List<Integer>> expected = UtUtils.stringToIntegerList2("[[1,4],[2,3],[3,2],[4,1]]");
14+
Assertions.assertEquals(expected, solution1237.findSolution(customfunction, z));
15+
}
16+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import java.util.PriorityQueue;
2+
3+
public class Solution1792 {
4+
public double maxAverageRatio(int[][] classes, int extraStudents) {
5+
// pass/total (pass+1)/(total+1)
6+
PriorityQueue<int[]> maxHeap = new PriorityQueue<>((o1, o2) -> {
7+
// (a+1)/(b+1) - a/b > (c+1)/(d+1) - c/d
8+
// (b-a)/b(b+1) > (d-c)/d(d+1)
9+
// (b-a)d(d+1) > (d-c)b(b+1)
10+
long val1 = (long) (o1[1] - o1[0]) * o2[1] * (o2[1] + 1);
11+
long val2 = (long) (o2[1] - o2[0]) * o1[1] * (o1[1] + 1);
12+
return Long.compare(val2, val1);
13+
});
14+
for (int[] cla : classes) {
15+
maxHeap.add(new int[]{cla[0], cla[1]});
16+
}
17+
18+
for (int i = 0; i < extraStudents; i++) {
19+
int[] poll = maxHeap.remove();
20+
maxHeap.add(new int[]{poll[0] + 1, poll[1] + 1});
21+
}
22+
23+
double sum = 0.0;
24+
while (!maxHeap.isEmpty()) {
25+
int[] poll = maxHeap.remove();
26+
sum += (double) poll[0] / poll[1];
27+
}
28+
return sum / classes.length;
29+
}
30+
}
31+
/*
32+
1792. 最大平均通过率
33+
https://leetcode.cn/problems/maximum-average-pass-ratio/
34+
35+
一所学校里有一些班级,每个班级里有一些学生,现在每个班都会进行一场期末考试。
36+
给你一个二维数组 classes ,其中 classes[i] = [passi, totali] ,表示你提前知道了第 i 个班级总共有 totali 个学生,其中只有 passi 个学生可以通过考试。
37+
给你一个整数 extraStudents ,表示额外有 extraStudents 个聪明的学生,他们 一定 能通过任何班级的期末考。你需要给这 extraStudents 个学生每人都安排一个班级,使得 所有 班级的 平均 通过率 最大 。
38+
一个班级的 通过率 等于这个班级通过考试的学生人数除以这个班级的总人数。平均通过率 是所有班级的通过率之和除以班级数目。
39+
请你返回在安排这 extraStudents 个学生去对应班级后的 最大 平均通过率。与标准答案误差范围在 10-5 以内的结果都会视为正确结果。
40+
提示:
41+
1 <= classes.length <= 10^5
42+
classes[i].length == 2
43+
1 <= passi <= totali <= 10^5
44+
1 <= extraStudents <= 10^5
45+
46+
贪心 + 大顶堆
47+
聪明的学生 优先分配给 通过率提升最大的班级
48+
通过率提升 = (a+1)/(b+1) - a/b
49+
*/
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution1792Tests {
5+
private final Solution1792 solution1792 = new Solution1792();
6+
// 与标准答案误差范围在 10-5 以内的结果都会视为正确结果。
7+
private static final double DELTA = 1e-5;
8+
9+
@Test
10+
public void example1() {
11+
int[][] classes = UtUtils.stringToInts2("[[1,2],[3,5],[2,2]]");
12+
int extraStudents = 2;
13+
double expected = 0.78333;
14+
Assertions.assertEquals(expected, solution1792.maxAverageRatio(classes, extraStudents), DELTA);
15+
}
16+
17+
@Test
18+
public void example2() {
19+
int[][] classes = UtUtils.stringToInts2("[[2,4],[3,9],[4,5],[2,10]]");
20+
int extraStudents = 4;
21+
double expected = 0.53485;
22+
Assertions.assertEquals(expected, solution1792.maxAverageRatio(classes, extraStudents), DELTA);
23+
}
24+
}

0 commit comments

Comments
 (0)