基于 jdk21
+ junit5
+ jacoco
的 leetcode + codeforces + atcoder + nowcoder + luogu 练习仓库。
@since
2021.07.05,Day 1413 (2025.05.17) 已收录:
- leetcode: 3195 题
- codeforces: 1021 题
- atcoder: 345 题
leetcode-n
存放100 * (n - 1) + 1
~100 * n
的题目(如leetcode-19
存放1801
~1900
的题目)。leetcode-extends
存放 专场竞赛/OJ 题目leetcode-interview
存放 《程序员面试金典》 题目。leetcode-lcp
存放 力扣杯 题目。leetcode-offer
存放 《剑指 Offer》 题目。数据库
题目存放于 https://gitee.com/gdut_yy/leetcode-hub-mysql
$ java -version
openjdk 21 2023-09-19
OpenJDK Runtime Environment (build 21+35-2513)
OpenJDK 64-Bit Server VM (build 21+35-2513, mixed mode, sharing)
$ mvn -v
Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: D:\programs\apache-maven-3.9.9
Java version: 21, vendor: Oracle Corporation, runtime: D:\programs\jdk-21
Default locale: zh_CN, platform encoding: UTF-8
OS name: "windows 11", version: "10.0", arch: "amd64", family: "windows"
IntelliJ IDEA 2024.2.2 (Community Edition)
Build #IC-242.22855.74, built on September 18, 2024
# 运行 UT、统计覆盖率(jdk21):
mvn clean verify -s settings.xml
# 统计做题进度(python3):
python countSolutions.py
java 项目中常见的测试框架:
mock 框架:
junit5 常用断言:
- Assertions.assertEquals
- Assertions.assertTrue
- Assertions.assertFalse
- Assertions.assertArrayEquals
思考:一些较为特殊的判题 UT 写法:
- 部分题目使用了自定义对象(链表、二叉树等),
Assertions.assertEquals
不能满足这种场景,可使用自定义断言对这类对象进行判等:ListNode
可参考ListNode#assertListNodeEquals(ListNode expected, ListNode actual)
,如第 2、19、21、23、82 题等;TreeNode
可参考TreeNode#assertTreeNodeEquals(TreeNode expected, TreeNode actual)
,如第 105、114、156、226、235 题等;- 不失一般性地,其他自定义对象可参考
UtUtils#assertJsonEquals(Object expected, Object actual)
,如第 138、430、708 题等;
- 部分题目符合题意的答案并不止一个,可以构造一个
List<T> expectedList
去判断是否contains()
如第 5、162 题等; - 部分题目符合题意的答案是一个集合,但对集合元素的顺序没有要求,可以对
expected
和actual
集合进行排序后判等:List<List<Integer>>
可参考UtUtils#INTEGER_LIST_COMPARATOR
,如第 18、39、40、46、47 题等;List<List<String>>
可参考UtUtils#STRING_LIST_COMPARATOR
,如第 49、51 题等;
- 部分题目是非精确判等(随机问题),如第 384、528 题等;
一些心得:
- leetcode 题目,可从
F12
控制台Request Payload
中mySubmissionDetail
关键词抓取; - 使用 Java 反射实现 UT 的题目:716、2227、2276、2286;
- 类中提供接口,UT 中需实现该接口:341、489、702、1095、1428、1533;
预计算结果是指:用户预先计算了部分或全部测试用例结果,并将其直接添加到至提交代码中。
规则及判分方式:如果参赛者的提交代码存在预计算结果的行为,我们建议参赛者附上生成预计算结果的代码。如参赛者含预计算结果的代码 “AC” 了题目,力扣将判定参赛者的提交为有效提交。
- 2286. 以组为单位订音乐会的门票 单点修改、区间求和、二分最小满足下标
快慢指针
- 19. 删除链表的倒数第 N 个结点
- 26. 删除有序数组中的重复项
- 27. 移除元素
- 83. 删除排序链表中的重复元素
- 141. 环形链表
- 142. 环形链表 II
- 283. 移动零
- 876. 链表的中间结点
二叉树前序遍历 (preorder)、中序遍历 (inorder)、后序遍历 (postorder)
扩展到 N 叉树(N 叉树没有 中序遍历)
二叉树层序遍历
二叉树序列化
其他
注意:Java 中 "栈" 应使用 Deque 代替 Stack(Java 官方建议)。即:
// Bad
Stack<T> stack = new Stack<>();
// Good
Deque<T> stack = new ArrayDeque<>();
注意二者转 stream 时的顺序:
Stack<Integer> stack1 = new Stack<>();
Deque<Integer> stack2 = new ArrayDeque<>();
stack1.push(1); stack1.push(2); stack1.push(3);
stack2.push(1); stack2.push(2); stack2.push(3);
System.out.println(Arrays.toString(stack1.stream().mapToInt(i -> i).toArray())); // [1, 2, 3]
System.out.println(Arrays.toString(stack2.stream().mapToInt(i -> i).toArray())); // [3, 2, 1]
// 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
public int singleNumber(int[] nums) {
int single = 0;
for (int num : nums) {
single ^= num;
}
return single;
}
// 给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。
public int singleNumber2(int[] nums) {
int a = 0;
int b = 0;
for (int num : nums) {
b = ~a & (b ^ num);
a = ~b & (a ^ num);
}
return b;
}
// 给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
public int[] singleNumber2(int[] nums) {
int xorsum = 0;
for (int num : nums) {
xorsum ^= num;
}
// 防止溢出
int lsb = (xorsum == Integer.MIN_VALUE ? xorsum : xorsum & (-xorsum));
int type1 = 0;
int type2 = 0;
for (int num : nums) {
if ((num & lsb) != 0) {
type1 ^= num;
} else {
type2 ^= num;
}
}
return new int[]{type1, type2};
}
- 877. 石子游戏
- 1140. 石子游戏 II
- 1406. 石子游戏 III
- 1510. 石子游戏 IV
- 1563. 石子游戏 V
- 1686. 石子游戏 VI
- 1690. 石子游戏 VII
- 1872. 石子游戏 VIII
- 2029. 石子游戏 IX
- 顶点 Vertex (复数 vertices)
- 边 Edge
- 有向图 directed graph
- 无向图 undirected graph
- 有向无环图 DAG (Directed Acyclic Graph)
- 入度 indegree
- 出度 outdegree
每次将入度为 0 的顶点加入队列。
- 200. 岛屿数量
- $323. 无向图中连通分量的数目
- 547. 省份数量
- 684. 冗余连接
- 765. 情侣牵手 [困难]
- 839. 相似字符串组
- 990. 等式方程的可满足性
- 1319. 连通网络的操作次数
- 1992. 找到所有的农场组
- 2076. 处理含限制条件的好友请求 [困难]
- Floyd 求任意两个结点之间的最短路。 时间复杂度 O(n^3)
- Dijkstra 求解 非负权图 上单源最短路径的算法。时间复杂度 O(n^2) / O(mlogn)
- Bellman ford 可以求出有负权的图的最短路 时间复杂度 O(mn)
Hierholzer 算法
二部图 Bipartite Graph
匈牙利算法(KM 算法)
- Prim(普里姆)算法
- Kruskal(克鲁斯卡尔)算法 边优先 O(mlogm) m 条边
- Ford-Fulkerson 算法(最坏情况时间复杂度 O(f*m) f 为最大流大小 m 为边的数量)
- Edmonds-Karp 算法 最短路 时间复杂度 O(n*m^2) n 为顶点数量 m 为边数量
- Dinic 算法 时间复杂度 O(m*n^2) level graph