leetcode hot100 力扣题目分类总结_力扣

第一讲 基础算法

(1) 排序

快速排序

归并排序

  1. LeetCode 56. 合并区间 >> 区间排序
(2) 前缀和与差分
  1. LeetCode.1248 统计优美子序列
  2. LeetCode 1191. K 次串联后最大子数组之和
  3. LeetCode 1170. 比较字符串最小字母出现频次
  4. LeetCode 1171. 从链表中删去总和值为零的连续节点 >> 前缀和+链表操作
  5. LeetCode 1177. 构建回文串检测
  6. LeetCode 1184. 公交站间的距离
  7. LeetCode 560. 和为K的子数组
  8. LeetCode 238. 除自身以外数组的乘积 >> 前缀积
  9. LeetCode 437. 路径总和 III >> 前缀和 + 哈希表 问题中出现某个前缀和出现多少次时,要想到使用哈希表转换为Si - T = Sj,求Sj的个数

(3) 二分
  1. LeetCode 35. 搜索插入位置
  2. LeetCode 74. 搜索二维矩阵
  3. LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置
  4. LeetCode 33. 搜索旋转排序数组
  5. LeetCode 153. 寻找旋转排序数组中的最小值 >> 同上

/* 版本1
当我们将区间[l, r]划分成[l, mid]和[mid + 1, r]时,其更新操作是r = mid或者l = mid + 1;,计算mid时不需要加1。
如果我们的目标是下面这个v,那麽就必须使用模板 1
................vooooooooo
*/

int bsearch_1(int l, int r)
{
    while (l < r)
    {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;
        else l = mid + 1;
    }
    return l;
}

/*
当我们将区间[l, r]划分成[l, mid - 1]和[mid, r]时,其更新操作是r = mid - 1或者l = mid;,此时为了防止死循环,计算mid时需要加1。

假设经由 check 划分后,整个区间的属性与目标v如下,则我们必须使用模板 2

oooooooov...................

所以下次可以观察 check 属性再与模板1 or 2 互相搭配就不会写错啦
*/
int bsearch_2(int l, int r)
{
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    return l;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
(4) 枚举与模拟
数组模拟与遍历
  1. LeetCode.1252 奇数值单元格的数目
  2. LeetCode.1253. 重构 2 行二进制矩阵
  3. LeetCode.1260. 二维网格迁移
  4. LeetCode 1207. 独一无二的出现次数
  5. LeetCode 54. 螺旋矩阵 >> 定义方向遍历
  6. LeetCode 48. 旋转图像
  7. LeetCode 240. 搜索二维矩阵 II >> 有序数组遍历 从右上角开始

字符串模拟
字符计数相关
  1. LeetCode 1221. 分割平衡字符串
  2. LeetCode 1234. 替换子串得到平衡字符串
  3. LeetCode 1247. 交换字符使得字符串相同
  4. LeetCode 1143. 最长公共子序列
  5. LeetCode 72. 编辑距离

字符前缀相关
  1. LeetCode 1233. 删除子文件夹

字符 栈运用
  1. LeetCode 1209. 删除字符串中的所有相邻重复项 II
  2. LeetCode 1190. 反转每对括号间的子串
双指针
  1. LeetCode 1156. 单字符重复子串的最大长度
  2. LeetCode 1169. 查询无效交易
  3. LeetCode 283. 移动零
  4. LeetCode 11. 盛最多水的容器 >> 有意思的双指针,贪心,移动短边
  5. LeetCode 15. 三数之和
  6. LeetCode 438. 找到字符串中所有字母异位词 >> 滑动窗口
  7. LeetCode 76. 最小覆盖子串 >> 注意左指针收缩的条件要满满足j - i 是一个正常的区间
  8. LeetCode 141. 环形链表 >> 判断环 快慢指针
  9. LeetCode 142. 环形链表 II >> 同上

// 滑动窗口
int left = 0, right = 0;
while (right < s.size()) {
    // 增大窗口
    window.add(s[right]);
    right++;
    
    while (window needs shrink) {
        // 缩小窗口
        window.remove(s[left]);
        left++;
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
枚举 (位运算,状态压缩等)
  1. LeetCode.1255 得分最高的单词集合
  2. LeetCode 1239. 串联字符串的最大长度
  3. LeetCode 1238. 循环码排列
  4. LeetCode 1240. 铺瓷砖
  5. LeetCode 1178. 猜字谜

方向枚举
  1. LeetCode 1222. 可以打击国王的皇后

分类讨论
  1. LeetCode 1224. 最大相等频率

第二 数据结构

(1) 并查集
  1. LeetCode 1202. 交换字符串中的元素
(2) 哈希表
  1. LeetCode 1160. 拼写单词
  2. LeetCode 1163. 按字典序排在最后的子串 // 哈希字符串
  3. LeetCode 1189. “气球” 的最大数量
  4. LeetCode 49. 字母异位词分组
  5. LeetCode 41. 缺失的第一个正数 >> 原地哈希:将数组本身当作哈希表
  6. LeetCode 73. 矩阵置零

(3) 栈
  1. LeetCode 20. 有效的括号
  2. LeetCode 155. 最小栈
  3. LeetCode 739. 每日温度 >> 单调栈
  4. LeetCode 84. 柱状图中最大的矩形
  5. LeetCode 32. 最长有效括号 ---- 括号相关

(4) 队列
  1. LeetCode 1172. 餐盘栈 >> 堆(优先队列)
  2. LeetCode 239. 滑动窗口最大值 >> 单调栈 双端队列
  3. LeetCode 23. 合并K个排序链表 >> 优先队列 priority_queue<int, vector, greater>小顶堆, priority_queue<int, vector> 大顶堆
  4. LeetCode 347. 前 K 个高频元素 >> 优先队列
  5. LeetCode 295. 数据流的中位数 >> 优先队列
(5) 链表
  1. LeetCode 83. 删除排序链表中的重复元素
  2. LeetCode 160. 相交链表
  3. LeetCode 206. 反转链表
  4. LeetCode 234. 回文链表
  5. LeetCode 21. 合并两个有序链表
  6. LeetCode 2. 两数相加 >> 两数相加,从个位开始,注意进位,有意思
  7. LeetCode 24. 两两交换链表中的节点 >> 将前面节点后面节点存下来
  8. LeetCode 25. K 个一组翻转链表 >> 分组翻转,翻转:前面的去链接最后面的,然后更新最后面的节点
  9. LeetCode 138. 复制带随机指针的链表 >> 深度复制
  10. LeetCode 146. LRU缓存机制 >> 双向链表
  11. LeetCode 114. 二叉树展开为链表

(5) 自定义结构
  1. LeetCode 155. 最小栈

第三讲 搜索与图论

(1) 搜索遍历
双指针
  1. LeetCode 1237. 找出给定方程的正整数解
  2. LeetCode 105. 从前序与中序遍历序列构造二叉树
  3. LeetCode 287. 寻找重复数 --- 快慢指针
  4. LeetCode 27. 移除元素
  5. LeetCode 26. 删除排序数组中的重复项
  6. LeetCode 88. 合并两个有序数组
(2) BFS
Flood Fill
  1. LeetCode.1254. 统计封闭岛屿的数目
  2. LeetCode 102. 二叉树的层序遍历
  3. LeetCode 199. 二叉树的右视图
  4. LeetCode 200. 岛屿数量

迷宫问题
  1. LeetCode 1210. 穿过迷宫的最少移动次数

多元bfs

  1. LeetCode 1162. 地图分析
  2. LeetCode 994. 腐烂的橘子

(3) DFS
// 树中序遍历 迭代算法  
vector<int> inorderTraversal(TreeNode* root) {
        // dfs(root);
        stack<TreeNode*> stk;
        while (root || stk.size()) {
            while (root) {
                stk.push(root);
                root = root->left;
            }
            if (stk.size()) {
                root = stk.top();
                stk.pop();
                s.push_back(root->val);
                root = root->right;
            }
        }
        return s;
    }
// 前序 迭代
class Solution {
public:
    void flatten(TreeNode* root) {
        auto v = vector<TreeNode*>();
        auto stk = stack<TreeNode*>();
        TreeNode *node = root;
        while (node != nullptr || !stk.empty()) {
            while (node != nullptr) {
                v.push_back(node);
                stk.push(node);
                node = node->left;
            }
            node = stk.top(); stk.pop();
            node = node->right;
        }
        int size = v.size();
        for (int i = 1; i < size; i++) {
            auto prev = v.at(i - 1), curr = v.at(i);
            prev->left = nullptr;
            prev->right = curr;
        }
    }
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  1. LeetCode 94. 二叉树的中序遍历 >> 树遍历迭代算法
  2. LeetCode 104. 二叉树的最大深度
  3. LeetCode 101. 对称二叉树
  4. LeetCode 543. 二叉树的直径
  5. LeetCode 98. 验证二叉搜索树
  6. LeetCode 230. 二叉搜索树中第K小的元素

回溯

  1. LeetCode 46. 全排列
  2. LeetCode 78. 子集
  3. LeetCode 17. 电话号码的字母组合
  4. LeetCode 39. 组合总和
  5. LeetCode 22. 括号生成
  6. LeetCode 79. 单词搜索
  7. LeetCode 51. N 皇后
  8. LeetCode 131. 分割回文串

最大最小路径问题
  1. LeetCode 1219. 黄金矿工
  2. LeetCode 1261. 在受污染的二叉树中查找元素
遍历
  1. LeetCode 1161. 最大层内元素和
(4) 图论
  1. LeetCode 207. 课程表
  2. LeetCode 208. 实现 Trie (前缀树)

(5) 分治
  1. LeetCode 108. 将有序数组转换为二叉搜索树
  2. LeetCode 236. 二叉树的最近公共祖先
  3. LeetCode 124. 二叉树中的最大路径和 >> 注意dfs的返回值为节点值、节点值加上左右指数的最大值。该返回值是提供给父节点使用,因此不能返回该值加上左和右。
  4. LeetCode 215. 数组中的第K个最大元素 >> 快速排序

// 快速排序算法模板 —— 模板题 
void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int i = l - 1, j = r + 1, x = q[l + r >> 1];
    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j) swap(q[i], q[j]);
    }
    quick_sort(q, l, j), quick_sort(q, j + 1, r);
}

// 归并排序算法模板
void merge_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int mid = l + r >> 1;
    merge_sort(q, l, mid);
    merge_sort(q, mid + 1, r);

    int k = 0, i = l, j = mid + 1;
    while (i <= mid && j <= r)
        if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];
        else tmp[k ++ ] = q[j ++ ];

    while (i <= mid) tmp[k ++ ] = q[i ++ ];
    while (j <= r) tmp[k ++ ] = q[j ++ ];

    for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.

第四讲 数学知识

(1) 约数
  1. LeetCode.1250
(2) 质数
  1. LeetCode 1175. 质数排列

(3) 欧拉函数
(4) 线性代数
  1. LeetCode 1232. 缀点成线

(5) 概率论
  1. LeetCode 1227. 飞机座位分配概率


(6) 扩展欧几里得算法

(7) 高斯消元

(8) 快速幂

(9)求组合数

(10) 容斥原理

(11) 博弈论

第五讲 动态规划

(1) 线性DP
  1. AcWing.898 数字三角形 -> LeetCode.1269 停在原地的方案数
  2. LeetCode.1278 分割回文串Ⅲ
  3. LeetCode.221 最大正方形+-*/ -> LeetCode.1277. 统计全为 1 的正方形子矩阵
  4. LeetCode 1218. 最长定差子序列
  5. LeetCode 1220. 统计元音字母序列的数目 -> LeetCode 1223. 掷骰子模拟
  6. LeetCode 1235. 规划兼职工作
  7. Acwing 走方格
  8. LeetCode 1186. 删除一次得到子数组最大和 >> 最大子区间和
  9. LeetCode 1187. 使数组严格递增 >> 最大上升子序列衍生
  10. LeetCode 42. 接雨水
  11. LeetCode 53. 最大子序和 >>
  12. LeetCode 70. 爬楼梯
  13. LeetCode 118. 杨辉三角 >> 二维线性规划
  14. LeetCode 198. 打家劫舍
  15. LeetCode 300. 最长上升子序列 >> 维护一个数组,这个数组存储这长度为k的序列最小结尾元素
  16. LeetCode 139. 单词拆分
  17. LeetCode 64. 最小路径和 >> 二维动态规划
  18. LeetCode 62. 不同路径 >> 二维动态规划
  19. LeetCode 5. 最长回文子串 --- 字符串相关
  20. LeetCode 1143. 最长公共子序列 --- 字符串相关
  21. LeetCode 72. 编辑距离 --- 字符串相关
(2) 背包问题
/*
1. 01背包
f[i][j] = max(f[i - 1][j], f[i - 1][j - v[i]] + w[i])

2. 完全背包
f[i][j] = max(f[i - 1][j], f[i][j - v[i]] + w[i])


*/
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

分组背包

  1. LeetCode 1155. 掷骰子的N种方法
  2. LeetCode 279. 完全平方数 >> 完全背包问题
  3. LeetCode 322. 零钱兑换 >> 装满与不装满的初始化区别 装满为f初始化大值,不装满为0
  4. LeetCode 416. 分割等和子集 >> 01背包

(3) 区间DP

  1. LeetCode 152. 乘积最大子数组

(4) 计数DP

(5) 状态压缩DP

(6) 数位DP

(7) 树形DP

(8) 记忆化DP

第六讲 贪心

(1) 数组相关
  1. LeetCode 1262. 可被三整除的最大和
  2. LeetCode 1217. 玩筹码
  3. LeetCode 121. 买卖的最佳时机
  4. LeetCode 55. 跳跃游戏 >> 更新最远点
  5. LeetCode 45. 跳跃游戏 II >> f(i)表示到达i坐标的最短步数,递增

(2) 区间问题
  1. LeetCode 763. 划分字母区间 >> 计算每个字符最后位置,扫描中不断更新位置,直到i = end为不可分割的一段;

(3) Huffman数

(4) 排序不等式

(5)绝对值不等式

(6) 推公式

第七讲 杂项

(1) 日期相关
  1. LeetCode 1154. 一年中的第几天
  2. LeetCode 1185. 一周中的第几天

(2) 数组相关
  1. LeetCode 189. 旋转数组
  2. LeetCode 169. 多数元素 >> 数组中袁术数量大于n/2的元素,为排序后的数组下边为n/2的元素
  3. LeetCode 31. 下一个排列 --- 字典序相关
(3) 运算相关
  1. LeetCode 136. 只出现一次的数字 >> 异或