Skip to content

Commit ab44ad2

Browse files
committed
一刷1349
1 parent b03c4e1 commit ab44ad2

10 files changed

+243
-53
lines changed

README.adoc

+6-6
Original file line numberDiff line numberDiff line change
@@ -9469,12 +9469,12 @@ TIP: **公众号的微信号是: `jikerizhi`**。__因为众所周知的原因
94699469
//|Medium
94709470
//|
94719471

9472-
//|{counter:codes}
9473-
//|{leetcode_base_url}/maximum-students-taking-exam/[1349. Maximum Students Taking Exam^]
9474-
//|{source_base_url}/_1349_MaximumStudentsTakingExam.java[Java]
9475-
//|{doc_base_url}/1349-maximum-students-taking-exam.adoc[题解]
9476-
//|Hard
9477-
//|
9472+
|{counter:codes}
9473+
|{leetcode_base_url}/maximum-students-taking-exam/[1349. Maximum Students Taking Exam^]
9474+
|{source_base_url}/_1349_MaximumStudentsTakingExam.java[Java]
9475+
|{doc_base_url}/1349-maximum-students-taking-exam.adoc[题解]
9476+
|Hard
9477+
|
94789478

94799479
//|{counter:codes}
94809480
//|{leetcode_base_url}/students-with-invalid-departments/[1350. Students With Invalid Departments^]
+56-46
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,73 @@
11
[#1349-maximum-students-taking-exam]
2-
= 1349. Maximum Students Taking Exam
2+
= 1349. 参加考试的最大学生数
33

4-
{leetcode}/problems/maximum-students-taking-exam/[LeetCode - 1349. Maximum Students Taking Exam ^]
4+
https://leetcode.cn/problems/maximum-students-taking-exam/[LeetCode - 1349. 参加考试的最大学生数 ^]
55

6-
Given a `m * n` matrix `seats` that represent seats distributions in a classroom. If a seat is broken, it is denoted by `'#'` character otherwise it is denoted by a `'.'` character.
6+
给你一个 `m * n` 的矩阵 `seats` 表示教室中的座位分布。如果座位是坏的(不可用),就用 `#` 表示;否则,用 `.` 表示。
77

8-
Students can see the answers of those sitting next to the left, right, upper left and upper right, but he cannot see the answers of the student sitting directly in front or behind him. Return the *maximum *number of students that can take the exam together without any cheating being possible.
8+
学生可以看到左侧、右侧、左上、右上这四个方向上紧邻他的学生的答卷,但是看不到直接坐在他前面或者后面的学生的答卷。请你计算并返回该考场可以容纳的同时参加考试且无法作弊的 **最大** 学生人数。
99

10-
Students must be placed in seats in good condition.
10+
学生必须坐在状况良好的座位上。
1111

12-
13-
*Example 1:*
14-
<img height="200" src="https://assets.leetcode.com/uploads/2020/01/29/image.png" width="339" />
15-
[subs="verbatim,quotes"]
16-
----
17-
*Input:* seats = [["#",".","#","#",".","#"],
18-
[".","#","#","#","#","."],
19-
["#",".","#","#",".","#"]]
20-
*Output:* 4
21-
*Explanation:* Teacher can place 4 students in available seats so they don't cheat on the exam.
22-
----
12+
*示例 1:*
2313

24-
*Example 2:*
14+
image::images/1349-01.png[{image_attr}]
2515

26-
[subs="verbatim,quotes"]
27-
----
28-
*Input:* seats = [[".","#"],
29-
["#","#"],
30-
["#","."],
31-
["#","#"],
32-
[".","#"]]
33-
*Output:* 3
34-
*Explanation:* Place all students in available seats.
16+
....
17+
输入:seats = [["#",".","#","#",".","#"],
18+
[".","#","#","#","#","."],
19+
["#",".","#","#",".","#"]]
20+
输出:4
21+
解释:教师可以让 4 个学生坐在可用的座位上,这样他们就无法在考试中作弊。
22+
....
3523

36-
----
24+
*示例 2:*
3725

38-
*Example 3:*
26+
....
27+
输入:seats = [[".","#"],
28+
["#","#"],
29+
["#","."],
30+
["#","#"],
31+
[".","#"]]
32+
输出:3
33+
解释:让所有学生坐在可用的座位上。
34+
....
3935

40-
[subs="verbatim,quotes"]
41-
----
42-
*Input:* seats = [["#",".","*.*",".","#"],
43-
["*.*","#","*.*","#","*.*"],
44-
["*.*",".","#",".","*.*"],
45-
["*.*","#","*.*","#","*.*"],
46-
["#",".","*.*",".","#"]]
47-
*Output:* 10
48-
*Explanation:* Place students in available seats in column 1, 3 and 5.
49-
----
36+
*示例 3:*
37+
38+
....
39+
输入:seats = [["#",".",".",".","#"],
40+
[".","#",".","#","."],
41+
[".",".","#",".","."],
42+
[".","#",".","#","."],
43+
["#",".",".",".","#"]]
44+
输出:10
45+
解释:让学生坐在第 1、3 和 5 列的可用座位上。
46+
....
5047

51-
52-
*Constraints:*
5348

49+
*提示:*
5450

55-
* `seats` contains only characters `'.'<font face="sans-serif, Arial, Verdana, Trebuchet MS"> and``'#'.`
51+
* `seats` 只包含字符 `.``#`
5652
* `m == seats.length`
5753
* `n == seats[i].length`
58-
* `1 <= m <= 8`
59-
* `1 <= n <= 8`
54+
* `+1 <= m <= 8+`
55+
* `+1 <= n <= 8+`
6056
6157
58+
== 思路分析
6259

60+
image::images/1349-10.png[{image_attr}]
6361

64-
== 思路分析
62+
image::images/1349-11.png[{image_attr}]
63+
64+
image::images/1349-12.png[{image_attr}]
6565

6666

6767
[[src-1349]]
6868
[tabs]
6969
====
70-
一刷::
70+
一刷(回溯,超时)::
7171
+
7272
--
7373
[{java_src_attr}]
@@ -76,6 +76,15 @@ include::{sourcedir}/_1349_MaximumStudentsTakingExam.java[tag=answer]
7676
----
7777
--
7878
79+
一刷::
80+
+
81+
--
82+
[{java_src_attr}]
83+
----
84+
include::{sourcedir}/_1349_MaximumStudentsTakingExam_1.java[tag=answer]
85+
----
86+
--
87+
7988
// 二刷::
8089
// +
8190
// --
@@ -89,4 +98,5 @@ include::{sourcedir}/_1349_MaximumStudentsTakingExam.java[tag=answer]
8998

9099
== 参考资料
91100

92-
101+
. https://leetcode.cn/problems/maximum-students-taking-exam/solutions/101748/can-jia-kao-shi-de-zui-da-xue-sheng-shu-by-leetcod/[1349. 参加考试的最大学生数 - 官方题解^]
102+
. https://leetcode.cn/problems/maximum-students-taking-exam/solutions/2580043/jiao-ni-yi-bu-bu-si-kao-dong-tai-gui-hua-9y5k/[1349. 参加考试的最大学生数 - 教你一步步思考动态规划:从记忆化搜索到递推^]

docs/images/1349-01.png

76.2 KB
Loading

docs/images/1349-10.png

436 KB
Loading

docs/images/1349-11.png

313 KB
Loading

docs/images/1349-12.png

266 KB
Loading

docs/index.adoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -2781,7 +2781,7 @@ include::1289-minimum-falling-path-sum-ii.adoc[leveloffset=+1]
27812781

27822782
// include::1348-tweet-counts-per-frequency.adoc[leveloffset=+1]
27832783

2784-
// include::1349-maximum-students-taking-exam.adoc[leveloffset=+1]
2784+
include::1349-maximum-students-taking-exam.adoc[leveloffset=+1]
27852785

27862786
// include::1350-students-with-invalid-departments.adoc[leveloffset=+1]
27872787

logbook/202503.adoc

+4
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,10 @@ endif::[]
688688
|{doc_base_url}/0918-maximum-sum-circular-subarray.adoc[题解]
689689
|❌ 理解错题目了。前大,中小,后大,这类子数组也可以产生更多的子数组和。另有“取反”和单调栈解法。
690690

691+
|{counter:codes2503}
692+
|{leetcode_base_url}/maximum-students-taking-exam/[1349. 参加考试的最大学生数^]
693+
|{doc_base_url}/1349-maximum-students-taking-exam.adoc[题解]
694+
|❌ 回溯解法通过 50 / 57 个测试用例。动态规划解法太难了!
691695

692696
|===
693697

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package com.diguage.algo.leetcode;
2+
3+
public class _1349_MaximumStudentsTakingExam {
4+
// tag::answer[]
5+
6+
/**
7+
* 通过 50 / 57 个测试用例,后超时。
8+
*
9+
* @author D瓜哥 · https://www.diguage.com
10+
* @since 2025-05-15 20:31:46
11+
*/
12+
int result = Integer.MIN_VALUE;
13+
14+
public int maxStudents(char[][] seats) {
15+
int seatNo = seats.length * seats[0].length - 1;
16+
backtrack(seats, seatNo, 0);
17+
return result;
18+
}
19+
20+
private void backtrack(char[][] seats, int seatNo, int num) {
21+
if (seatNo < 0) {
22+
result = Math.max(result, num);
23+
return;
24+
}
25+
int row = seatNo / seats[0].length;
26+
int column = seatNo % seats[0].length;
27+
if (seats[row][column] == '.') {
28+
for (int i = 1; i >= 0; i--) {
29+
if (i == 0) {
30+
seats[row][column] = '0';
31+
backtrack(seats, seatNo - 1, num);
32+
seats[row][column] = '.';
33+
} else {
34+
seats[row][column] = '1';
35+
// 左
36+
boolean left = false;
37+
if (column > 0 && seats[row][column - 1] == '.') {
38+
left = true;
39+
seats[row][column - 1] = '0';
40+
}
41+
// 左上
42+
boolean leftUp = false;
43+
if (row > 0 && column > 0
44+
&& seats[row - 1][column - 1] == '.') {
45+
leftUp = true;
46+
seats[row - 1][column - 1] = '0';
47+
}
48+
// 右
49+
boolean right = false;
50+
if (column < seats[0].length - 1 && seats[row][column + 1] == '.') {
51+
right = true;
52+
seats[row][column + 1] = '0';
53+
}
54+
// 右上
55+
boolean rightUp = false;
56+
if (row > 0 && column < seats[row].length - 1
57+
&& seats[row - 1][column + 1] == '.') {
58+
rightUp = true;
59+
seats[row - 1][column + 1] = '0';
60+
}
61+
62+
backtrack(seats, seatNo - 1, num + 1);
63+
64+
// 右上
65+
if (rightUp) {
66+
seats[row - 1][column + 1] = '.';
67+
}
68+
// 右
69+
if (right) {
70+
seats[row][column + 1] = '.';
71+
}
72+
// 左上
73+
if (leftUp) {
74+
seats[row - 1][column - 1] = '.';
75+
}
76+
// 左
77+
if (left) {
78+
seats[row][column - 1] = '.';
79+
}
80+
seats[row][column] = '.';
81+
}
82+
}
83+
} else {
84+
backtrack(seats, seatNo - 1, num);
85+
}
86+
}
87+
// end::answer[]
88+
89+
public static void main(String[] args) {
90+
new _1349_MaximumStudentsTakingExam().maxStudents(new char[][]{
91+
{'.', '.', '.', '.', '#', '.', '.', '.'},
92+
{'.', '.', '.', '.', '.', '.', '.', '.'},
93+
{'.', '.', '.', '.', '.', '.', '.', '.'},
94+
{'.', '.', '.', '.', '.', '.', '#', '.'},
95+
{'.', '.', '.', '.', '.', '.', '.', '.'},
96+
{'.', '.', '#', '.', '.', '.', '.', '.'},
97+
{'.', '.', '.', '.', '.', '.', '.', '.'},
98+
{'.', '.', '.', '#', '.', '.', '#', '.'}
99+
// {'.', '#', '.', '#'},
100+
// {'.', '.', '.', '#'},
101+
// {'#', '#', '.', '.'},
102+
// {'.', '#', '#', '#'}
103+
// {'.', '#', '.', '#'},
104+
// {'.', '.', '.', '#'},
105+
// {'#', '#', '.', '.'},
106+
// {'.', '#', '#', '#'}
107+
// {'#', '.', '#', '#', '.', '#'},
108+
// {'.', '#', '#', '#', '#', '.'},
109+
// {'#', '.', '#', '#', '.', '#'}
110+
});
111+
}
112+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.diguage.algo.leetcode;
2+
3+
public class _1349_MaximumStudentsTakingExam_1 {
4+
// tag::answer[]
5+
/**
6+
* @author D瓜哥 · https://www.diguage.com
7+
* @since 2025-05-15 20:31:46
8+
*/
9+
public int maxStudents(char[][] seats) {
10+
int m = seats.length;
11+
int n = seats[0].length;
12+
int[] a = new int[m]; // a[i] 是第 i 排可用椅子的下标集合
13+
for (int i = 0; i < m; i++) {
14+
for (int j = 0; j < n; j++) {
15+
if (seats[i][j] == '.') {
16+
a[i] |= 1 << j;
17+
}
18+
}
19+
}
20+
int[][] f = new int[m][1 << n];
21+
for (int j = 1; j < (1 << n); j++) {
22+
int lb = j & -j;
23+
f[0][j] = f[0][j & ~(lb * 3)] + 1;
24+
}
25+
for (int i = 1; i < m; i++) {
26+
for (int j = a[i]; j > 0; j = (j - 1) & a[i]) { // 枚举 a[i] 的子集 j
27+
f[i][j] = f[i - 1][a[i - 1]]; // 第 i 排空着
28+
for (int s = j; s > 0; s = (s - 1) & j) { // 枚举 j 的子集 s
29+
if ((s & (s >> 1)) == 0) {// s 没有连续的 1
30+
int t = a[i - 1] & ~(s << 1 | s >> 1); // 去掉不能坐人的位置
31+
f[i][j] = Math.max(f[i][j], f[i - 1][t] + f[0][s]);
32+
}
33+
}
34+
}
35+
f[i][0] = f[i - 1][a[i - 1]];
36+
}
37+
return f[m - 1][a[m - 1]];
38+
}
39+
// end::answer[]
40+
41+
public static void main(String[] args) {
42+
new _1349_MaximumStudentsTakingExam_1().maxStudents(new char[][]{
43+
{'.', '.', '.', '.', '#', '.', '.', '.'},
44+
{'.', '.', '.', '.', '.', '.', '.', '.'},
45+
{'.', '.', '.', '.', '.', '.', '.', '.'},
46+
{'.', '.', '.', '.', '.', '.', '#', '.'},
47+
{'.', '.', '.', '.', '.', '.', '.', '.'},
48+
{'.', '.', '#', '.', '.', '.', '.', '.'},
49+
{'.', '.', '.', '.', '.', '.', '.', '.'},
50+
{'.', '.', '.', '#', '.', '.', '#', '.'}
51+
// {'.', '#', '.', '#'},
52+
// {'.', '.', '.', '#'},
53+
// {'#', '#', '.', '.'},
54+
// {'.', '#', '#', '#'}
55+
// {'.', '#', '.', '#'},
56+
// {'.', '.', '.', '#'},
57+
// {'#', '#', '.', '.'},
58+
// {'.', '#', '#', '#'}
59+
// {'#', '.', '#', '#', '.', '#'},
60+
// {'.', '#', '#', '#', '#', '.'},
61+
// {'#', '.', '#', '#', '.', '#'}
62+
});
63+
}
64+
}

0 commit comments

Comments
 (0)