灵茶山算法基础笔记

转载自大佬整理的题单,太强了🙌 : 灵茶山艾府

基础算法精讲·题目汇总大家好,我是 灵茶山艾府。

我制作了一系列算法教学视频,整理成合集【基础算法精讲】。以下是合集中的视频链接、配套题目和代码,代码包含 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 国际 许可协议,转载请注明出处。

友情链接: