转载自大佬整理的题单,太强了🙌 : 灵茶山艾府
基础算法精讲·题目汇总大家好,我是 灵茶山艾府。
我制作了一系列算法教学视频,整理成合集【基础算法精讲】。以下是合集中的视频链接、配套题目和代码,代码包含 Python/Java/C++/Go 等多种语言。
制作不易,欢迎点赞,也欢迎转发给你的朋友或刷题群!
视频精讲
题目
代码
备注
相向双指针 1
167. 两数之和 II - 输入有序数组
代码
15. 三数之和
代码
包含两个优化
2824. 统计和小于目标的下标对数目
代码
*课后作业
16. 最接近的三数之和
代码
*课后作业
18. 四数之和
代码
*课后作业
611. 有效三角形的个数
代码
*课后作业
相向双指针 2
11. 盛最多水的容器
代码
42. 接雨水
代码
额外讲了前后缀分解
125. 验证回文串
代码
*课后作业
2105. 给植物浇水 II
代码
*课后作业
滑动窗口
209. 长度最小的子数组
代码
最短
3. 无重复字符的最长子串
代码
最长
713. 乘积小于 K 的子数组
代码
方案数
2958. 最多 K 个重复元素的最长子数组
代码
*课后作业
2730. 找到最长的半重复子字符串
代码
*课后作业
2779. 数组的最大美丽值
代码
*课后作业
1004. 最大连续 1 的个数 III
代码
*课后作业
2962. 统计最大元素出现至少 K 次的子数组
代码
*课后作业
2302. 统计得分小于 K 的子数组数目
代码
*课后作业
1658. 将 x 减到 0 的最小操作数
代码
*课后作业
1234. 替换子串得到平衡字符串
代码
*课后作业
76. 最小覆盖子串
代码
*课后作业
二分查找
34. 在排序数组中查找元素的第一个和最后一个位置
代码
三种写法
2529. 正整数和负整数的最大计数
代码
*课后作业
2300. 咒语和药水的成功对数
代码
*课后作业
2563. 统计公平数对的数目
代码
*课后作业
2080. 区间内查询数字的频率
代码
*课后作业
275. H 指数 II
代码
*课后作业
875. 爱吃香蕉的珂珂
代码
*课后作业
2187. 完成旅途的最少时间
代码
*课后作业
2861. 最大合金数
代码
*课后作业
2439. 最小化数组中的最大值
代码
*课后作业
2517. 礼盒的最大甜蜜度
代码
*课后作业
二分查找 - 变形
162. 寻找峰值
代码
153. 寻找旋转排序数组中的最小值
代码
33. 搜索旋转排序数组
代码
两种方法
74. 搜索二维矩阵
代码
*课后作业
1901. 寻找峰值 II
代码
*课后作业
154. 寻找旋转排序数组中的最小值 II
代码
*课后作业
链表 - 反转系列
206. 反转链表
代码
92. 反转链表 II
代码
25. K 个一组翻转链表
代码
24. 两两交换链表中的节点
代码
*课后作业
445. 两数相加 II
代码
*课后作业
2816. 翻倍以链表形式表示的数字
代码
*课后作业
链表 - 快慢指针
876. 链表的中间结点
代码
141. 环形链表
代码
142. 环形链表 II
代码
143. 重排链表
代码
234. 回文链表
代码
*课后作业
链表 - 删除系列
237. 删除链表中的节点
代码
脑筋急转弯
19. 删除链表的倒数第 N 个结点
代码
前后指针
83. 删除排序链表中的重复元素
代码
82. 删除排序链表中的重复元素 II
代码
203. 移除链表元素
代码
*课后作业
3217. 从链表中移除在数组中存在的节点
代码
*课后作业
2487. 从链表中移除节点
代码
*课后作业
二叉树与递归 - 深入理解
104. 二叉树的最大深度
代码
两种方法
111. 二叉树的最小深度
代码
*课后作业
112. 路径总和
代码
*课后作业
129. 求根节点到叶节点数字之和
代码
*课后作业
1448. 统计二叉树中好节点的数目
代码
*课后作业
987. 二叉树的垂序遍历
代码
*课后作业
二叉树与递归 - 灵活运用
100. 相同的树
代码
101. 对称二叉树
代码
110. 平衡二叉树
代码
199. 二叉树的右视图
代码
226. 翻转二叉树
代码
*课后作业
617. 合并二叉树
代码
*课后作业
1026. 节点与其祖先之间的最大差值
代码
*课后作业
1080. 根到叶路径上的不足节点
代码
*课后作业
二叉树与递归 - 前序/中序/后序
98. 验证二叉搜索树
代码
三种方法
938. 二叉搜索树的范围和
代码
*课后作业
2476. 二叉搜索树最近节点查询
代码
*课后作业
230. 二叉搜索树中第 K 小的元素
代码
*课后作业
1373. 二叉搜索子树的最大键值和
代码
*课后作业
105. 从前序与中序遍历序列构造二叉树
代码
*课后作业
106. 从中序与后序遍历序列构造二叉树
代码
*课后作业
889. 根据前序和后序遍历构造二叉树
代码
*课后作业
1110. 删点成林
代码
*课后作业
二叉树与递归 - 最近公共祖先
236. 二叉树的最近公共祖先
代码
235. 二叉搜索树的最近公共祖先
代码
1123. 最深叶节点的最近公共祖先
代码
*课后作业
二叉树 - BFS
102. 二叉树的层序遍历
代码
两种写法
103. 二叉树的锯齿形层序遍历
代码
两种写法
513. 找树左下角的值
代码
107. 二叉树的层序遍历 II
代码
*课后作业
116. 填充每个节点的下一个右侧节点指针
代码
*课后作业
117. 填充每个节点的下一个右侧节点指针 II
代码
*课后作业
2415. 反转二叉树的奇数层
代码
*课后作业
2641. 二叉树的堂兄弟节点 II
代码
*课后作业
回溯 - 子集型
17. 电话号码的字母组合
代码
引入回溯概念用
78. 子集
代码
两种写法
131. 分割回文串
代码
两种写法
2698. 求一个整数的惩罚数
代码
*课后作业
回溯 - 组合型与剪枝
77. 组合
代码
两种写法
216. 组合总和 III
代码
两种写法
22. 括号生成
代码
两种写法
39. 组合总和
代码
*课后作业
93. 复原 IP 地址
代码
*课后作业
回溯 - 排列型
46. 全排列
代码
精确计算搜索树的节点个数
51. N 皇后
代码
52. N 皇后 II
代码
2850. 将石头分散到网格图的最少移动次数
代码
*课后作业
动态规划 - 从记忆化搜索到递推
198. 打家劫舍
代码
包含空间优化
70. 爬楼梯
代码
*课后作业
746. 使用最小花费爬楼梯
代码
*课后作业
377. 组合总和 Ⅳ
代码
*课后作业
2466. 统计构造好字符串的方案数
代码
*课后作业
2266. 统计打字方案数
代码
*课后作业
213. 打家劫舍 II
代码
*课后作业
64. 最小路径和
代码
*课后作业
0-1 背包 完全背包 至多/恰好/至少
494. 目标和
代码
包含空间优化
322. 零钱兑换
代码
包含空间优化
2915. 和为目标值的最长子序列的长度
代码
*课后作业
416. 分割等和子集
代码
*课后作业
518. 零钱兑换 II
代码
*课后作业
279. 完全平方数
代码
*课后作业
最长公共子序列 LCS
1143. 最长公共子序列
代码
包含空间优化
72. 编辑距离
代码
包含空间优化
97. 交错字符串
代码
*课后作业
1092. 最短公共超序列
代码
*课后作业
最长递增子序列 LIS
300. 最长递增子序列
代码
包括贪心二分 + $O(1)$ 空间
1671. 得到山形数组的最少删除次数
代码
*课后作业
1626. 无矛盾的最佳球队
代码
*课后作业
状态机 DP - 买卖股票系列
122. 买卖股票的最佳时机 II
代码
309. 买卖股票的最佳时机含冷冻期
代码
188. 买卖股票的最佳时机 IV
代码
变形:恰好/至少
714. 买卖股票的最佳时机含手续费
代码
*课后作业
2826. 将三个组排序
代码
*课后作业
2786. 访问数组中的位置使分数最大
代码
*课后作业
区间 DP
516. 最长回文子序列
代码
包含空间优化
1039. 多边形三角剖分的最低得分
代码
3040. 相同分数的最大操作数目 II
代码
*课后作业
1547. 切棍子的最小成本
代码
*课后作业
1771. 由子序列构造的最长回文串的长度
代码
*课后作业
1000. 合并石头的最低成本
代码
*课后作业
树形 DP - 直径系列
543. 二叉树的直径
代码
124. 二叉树中的最大路径和
代码
2246. 相邻字符不同的最长路径
代码
687. 最长同值路径
代码
*课后作业
3203. 合并两棵树后的最小直径
代码
*课后作业
1617. 统计子树中城市之间最大距离
代码
*课后作业
2538. 最大价值和与最小价值和的差值
代码
*课后作业
树形 DP - 最大独立集
337. 打家劫舍 III
代码
1377. T 秒后青蛙的位置
代码
*课后作业
2646. 最小化旅行的价格总和
代码
*课后作业
树形 DP - 最小支配集
968. 监控二叉树
代码
单调栈
739. 每日温度
代码
两种写法
42. 接雨水
代码
496. 下一个更大元素 I
代码
*课后作业
503. 下一个更大元素 II
代码
*课后作业
901. 股票价格跨度
代码
*课后作业
1019. 链表中的下一个更大节点
代码
*课后作业
1944. 队列中可以看到的人数
代码
*课后作业
84. 柱状图中最大的矩形
代码
*课后作业
1793. 好子数组的最大分数
代码
*课后作业
85. 最大矩形
代码
*课后作业
单调队列
239. 滑动窗口最大值
代码
2398. 预算内的最多机器人数目
代码
*课后作业
862. 和至少为 K 的最短子数组
代码
*课后作业
1499. 满足不等式的最大值
代码
*课后作业
1696. 跳跃游戏 VI
代码
*课后作业
2944. 购买水果需要的最少金币数
代码
*课后作业
其他尚未更新的 topic 请看 题解精选(已分类)
算法题单🔥如何科学刷题?
滑动窗口与双指针(定长/不定长/单序列/双序列/三指针/分组循环)
二分算法(二分答案/最小化最大值/最大化最小值/第K小)
单调栈(基础/矩形面积/贡献法/最小字典序)
网格图(DFS/BFS/综合应用)
位运算(基础/性质/拆位/试填/恒等式/思维)
图论算法(DFS/BFS/拓扑排序/最短路/最小生成树/二分图/基环树/欧拉路径)
🔥动态规划(入门/背包/状态机/划分/区间/状压/数位/数据结构优化/树形/博弈/概率期望)
常用数据结构(前缀和/差分/栈/队列/堆/字典树/并查集/树状数组/线段树)
数学算法(数论/组合/概率期望/博弈/计算几何/随机算法)
贪心与思维(基本贪心策略/反悔/区间/字典序/数学/思维/脑筋急转弯/构造)
链表、二叉树与回溯(前后指针/快慢指针/DFS/BFS/直径/LCA/一般树)
字符串(KMP/Z函数/Manacher/字符串哈希/AC自动机/后缀数组/子序列自动机)
周赛总结
如何科学上分(科学刷题)
从周赛中学算法 - 2023·下
从周赛中学算法 - 2023·上
从周赛中学算法 - 2022·下
从周赛中学算法 - 2022·上
其他
🔥从集合论到位运算,常见位运算技巧分类总结!
模运算的世界:当加减乘除遇上取模
【简单题杀手】分组循环
【图解】一张图秒懂二维前缀和
相向双指针小tips:可以通过获取的信息量来衡量一个算法的效率.
双指针的精髓:用O1的时间,获取到On的信息.(因为每次移动都能够排除多个不可能的组合)
167. 两数之和 II - 输入有序数组比如这道题目暴力做法枚举每个数,然后和target作比较,O1的时间就获取到了O1的信息.而双指针的方法将剩下的数和最大的数对比,O1的时间获取到了On的信息.
线段树以这道题目水果成篮III为例,入门线段树.
线段树发明的动机虽然说数组无序,但是仍然可以通过二分的方式寻找需要的位置,如果左半边有就排除右半边,如果左半边没有就排除左半边.并且每次二分,都是原问题相同的更小子问题,也就是继续寻找左右半边最大的容器.
为什么要这么设计线段树通过线段树,可以维护所有需要的情况的数据.并且在查找后,需要重新修正节点.所以需要的操作就是:找到最左边大于等于x的位置;将该位置改成-1.
线段树模板123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960class SegmentTree { private final int[] max; public SegmentTree(int[] a) { int n = a.length; //max是大于或等于 n的最小的 2 的幂次方 max = new int[2 << (32 - Integer.numberOfLeadingZeros(n - 1))]; //建立线段树 build(a, 1, 0, n - 1); } // 找区间内的第一个 >= x 的数,并更新为 -1,返回这个数的下标(没有则返回 -1) //o为第几个位置 l为左下标 r为右下标 x为目标数 public int findFirstAndUpdate(int o, int l, int r, int x) { if (max[o] < x) { // 区间没有 >= x 的数 return -1; } if (l == r) { max[o] = -1; // 更新为 -1,表示不能放水果 return l; } int m = (l + r) / 2; int i = findFirstAndUpdate(o * 2, l, m, x); // 先递归左子树 if (i < 0) { // 左子树没找到 i = findFirstAndUpdate(o * 2 + 1, m + 1, r, x); // 再递归右子树 } maintain(o); return i; } //在回溯过程更新节点 private void maintain(int o) { max[o] = Math.max(max[o * 2], max[o * 2 + 1]); } // 初始化线段树 private void build(int[] a, int o, int l, int r) { if (l == r) { max[o] = a[l]; return; } int m = (l + r) / 2; build(a, o * 2, l, m); build(a, o * 2 + 1, m + 1, r); maintain(o); }}class Solution { public int numOfUnplacedFruits(int[] fruits, int[] baskets) { SegmentTree t = new SegmentTree(baskets); int n = baskets.length; int ans = 0; for (int x : fruits) { if (t.findFirstAndUpdate(1, 0, n - 1, x) < 0) { ans++; } } return ans; }}
许可协议
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 许可协议,转载请注明出处。