前言
- 花费两个月刷完了代码随想录,通过分类型地学习与做题,让我对算法有了更深入的认识,打下了牢固的基础,感谢代码随想录,感谢carl哥!
一、数组
- 一般数组、字符串(可以转为字符数组)都可以考虑以下方法
二分查找
- 遇到数组有序,且无重复元素
- 数组无序也可考虑排序,有重复元素也可考虑使用二分法查找左右边界
- 时间复杂度O(logn)
- 应用:数组的查找问题
- 题目
双指针
- 快慢指针:两个指针都从头开始,速度不一样。一个for循环实现两个for循环的功能
- 左右指针(对撞指针):两个指针分别从首尾出发,速度看情况。
- 两个指针可以指向同一个数组,也可以分别指向不同数组
- 题目
滑动窗口
- 实际上依赖双指针:快慢指针分别指向窗口左右边界
- 固定窗口大小
- 动态更新窗口大小
- 应用:求某个子串或子数组的最值问题,或求某个目标值。
- 题目
螺旋矩阵
二、链表
- 操作链表时尽量设置虚拟头节点指向链表头节点,处理完后返回虚拟头节点的next即可,这样不需要对链表头节点单独拉出来处理。
- 链表的增删改查
- 题目
三、哈希表
- 将数组作为哈希表,每个下标对应一个key:一般是限定了输入范围,数字、小写字母、大写字母等
- 求交集、需要去重的情况使用set
- HashMap
- 题目
四、字符串
- 字符串也常用双指针法
- KMP:使用前缀表解决匹配问题和重复子串问题
- 题目
五、双指针
- 针对数组、字符串和链表问题都可以使用双指针,降低时间复杂度
- N数之和,三数、四数之和用双指针,两数之和用哈希表
- 之前使用双指针的题目
六、栈与队列
- 理解栈和队列的原理,两个栈实现队列、一个队列实现栈。
- 栈解决匹配问题(括号匹配、逆波兰表达式)、字符串去重问题
- 单调队列:维护队列中元素递增或递减(手动实现)
- 优先级队列:大(小)顶堆,priorityQueue默认是大顶堆
- 求前k大使用小顶堆;求前k小使用大顶堆
- 题目
七、*二叉树
- 二叉树问题一定要掌握递归!递归时注意前中后序的要求!
7.1 二叉树的遍历
7.2 二叉树的属性
- 二叉树深度:
- 二叉树高度:
- 递归函数有返回值:找到一条符合条件的路径即可
- 递归函数没有返回值:找到所有符合条件的路径
- 题目
7.3 二叉树的修改与改造
- 构造二叉树:前序和中序、后序和中序可以唯一确定一颗二叉树。构造时直接通过下标索引操作原数组节省空间,注意下标边界。
- 需要同时操作两个二叉树时使用队列模拟层序遍历。
- 题目
7.4 求二叉搜索树的属性
- 二叉搜索树:左子树比根节点小,右子树比根节点大。中序遍历为有序数组
- 完全二叉树:每一层左侧节点是满的
- 满二叉树:每一层的节点都是满的
- 满二叉树一定是完全二叉树,完全二叉树不一定是满二叉树
- 题目
7.5 二叉树公共祖先问题
7.6 二叉搜索树的修改与改造
八、*回溯算法
8.1 组合
- 求一个集合符合条件的组合需要使用startIndex来控制递归的起始下标
- 求多个互相不影响的集合符合条件的组合可以不使用startIndex
- 注意剪枝优化和结果去重
- 时间复杂度O(n * 2 ^ n),空间复杂度O(n)
- 题目
8.2 分割
8.3 子集
- 子集问题需要收集所有节点的结果,组合问题需要收集叶子节点的结果
- 同样注意剪枝和去重问题
- 时间复杂度O(n * 2 ^ n),空间复杂度O(n)
- 题目
8.4 排列
- 排列是有序的,组合是无序的;排列每次都从下标0开始,组合是从startIndex开始
- 排列需要使用used数组记录使用过的元素来去重
- 时间复杂度O(n !),空间复杂度O(n)
- 题目
8.5 棋盘问题
- 二维递归回溯
- 题目
- 51 N皇后
- 37 解数独
- 时间复杂度O(9 ^ m),空间复杂度O(n ^ 2)
8.6 其他
九、贪心算法
9.1 简单
9.2 中等
9.2.1 序列问题
9.2.2 *股票问题
9.2.3 两个维度权衡问题
9.3 较难
9.3.1 *区间问题
9.3.2 其他
十、*动态规划DP
- 动规五步:定义dp数组、确定递推公式、初始化dp数组、确定遍历顺序、举例
10.1 基础题目
10.2 *背包问题
10.2.1 01背包
- 二维dp数组dp[i][j]表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是dp[i][j]。注意遍历顺序都可以(小到大)
- 使用一维滚动数组dp[j]优化,表示容量为j的背包,所背的物品价值可以最大为dp[j]。注意遍历顺序为先物品(i小到大)后背包(j大到小,防止物品放入多次)
- 题目
10.2.2 完全背包
- 使用一维滚动数组,注意遍历顺序都可以(小到大,物品可以放入多次),如果不是求组合或排列,一般先物品后背包,没那么容易弄混
- 如果求组合数,先物品后背包
- 如果求排列数,先背包后物品
- 题目
10.3 打家劫舍
10.4 股票问题
- 考虑每天可能存在的状态
- 题目
- 121 买卖股票的最佳时机(只能买卖一次)、122 买卖股票的最佳时机II(可以买卖多次)、123 买卖股票的最佳时机III(最多买卖两次)、188 买卖股票的最佳时机IV(最多买卖k次)、309 买卖股票的最佳时机含冷冻期(买卖多次,卖出有一天冷冻期)、714 买卖股票的最佳时机含手续费(买卖多次,每次有手续费)
10.5 子序列问题
10.5.1 子序列(不连续)
- 300 最长上升子序列、1143 最长公共子序列、1035 不相交的线
10.5.2 子序列(连续)
- 674 最长连续递增序列、718 最长重复子数组、53 最大子序和
10.5.3 编辑距离
10.5.4 回文
十一、单调栈
|