[TOC]
- 递归
- 迭代
- 递归
- 递归
- 迭代
- 双指针
- 遍历(不推荐)
- 栈
- 哈希表
- 暴力枚举
- 滑动窗口
- 迭代
- 当前节点绕过下一个节点,并将当前节点完全改造成下一个节点
- 递归
- 迭代
- 回溯法
- 只要求返回数量,使用动态规划
- 递归
- 中序遍历
- 递归
- 迭代
- 动态规划
- 动态规划
- 深度搜索
- 广度搜索
- LinkedHashMap(并不会写,要时常回顾)
- 中序遍历
- 迭代
- 递归
- 难度为Hard是因为该题鼓励使用Morris算法进行二叉树遍历,暂时不考虑
- DFS (常规解法递归)
- BFS (超时)
- 利用完全二叉树的特性
- 栈
- 双指针
- 双指针
- 哈希表
- 快慢指针
- 哈希表
- 快速排序
- 哈希排序
- 堆并排序
……
- 排序
- 回溯算法
- 列竖式
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 股票问题均考虑用动态规划
- 迭代法
- 递归法
- 双指针、头插法
- 递归法
- 动态规划
-
链表的后序遍历
-
快慢指针
-
或者将链表复制到数组以后双指针
- 头插法
- 哈希
- 快慢指针
- BFS
- 多源BFS
- 动态规划
- BFS
- 双端队列
- BFS
- List.add(0,node)
- 双指针
- 栈
- DFS
- 二分查找
- 二分查找
- 递归
- 哈希表
- 快慢指针
- 矩阵
- BFS
- DFS
- 动态规划
- 中心扩展算法
- 动态规划
- 动态规划
- 双栈
- 牛顿法
- 二分查找
- 动态规划
- 动态规划
- DFS
- 动态规划
- 二分查找
- 数学
- (randX() - 1)*Y + randY() 可以等概率的生成[1, X * Y]范围的随机数
- 单队列
- 双队列
-
线性表list可以简单获取链表
-
寻找链表中点 + 链表逆序 + 合并链表
- 求中间链表可用快慢链表
- 快慢链表
- 注意中间前一个节点和中间后一个节点的写法不一样
- DFS,BFS进行层序遍历
- 字符串处理
- 自动机
-
动态规划(硬币找零问题)
-
本身是完全背包问题
- 递归
- 迭代
- 递归
- 迭代
- 迭代中有一种方法:基于前序遍历 根 -> 左 -> 右的顺序,易得 根 -> 右 -> 左 的顺序,逆序即可得到 左->右->根的顺序,即为后序遍历的方法。但是这种不符合对题目的理解,在面试中不合适
- 要对节点是否访问过进行记录,可以使用prev进行判断
- 排序后进行合并
- List 转数组 ans.toArray(new int[m] [n])
- List 的赋值方式 ans.get(m) = a
- 数组的复制 Arrays.copyOf(res, idx + 1)
- 数组创建默认值为0
- lambda表达式/函数式编程 Arrays.sort(intervals, (v1,v2)->v1[0]-v2[0])
- 调用API
- Arrays.asList 转list
- 多个空白字符匹配 s.split("\s+")
- 字符串连接 String.join(" ",list)
- 考虑先进后出的特性,使用栈(Deque)
- StringBuild 清空:setLength(0)
- 全排列的相关理解:如何让混乱度增加的同时,数组的变化尽可能小
- 深度优先搜索
- 广度优先搜索
- 递归
- 迭代(暂时不想看了)
- 深度优先搜索
- 动态规划
- 深度优先搜索 :要求维护层数和总数
- 广度优先搜索
-
先序遍历
-
迭代
-
递归:注意相连时用快慢指针
-
-
暴力解:右子树移到左子树最右最下,整个左子树再移到右子树的位置上
-
要求不需要额外空间,考虑使用morris
- 自顶向下的递归
- 自底向上的递归
- 自底向上递归的做法类似于后序遍历,对于当前遍历到的节点,先递归地判断其左右子树是否平衡,再判断以当前节点为根的子树是否平衡。如果一棵子树是平衡的,则返回其高度(高度一定是非负整数),否则返回 -1−1。如果存在一棵子树不平衡,则整个二叉树一定不平衡。
- 本质上是前序遍历和后序遍历的区别
- 和124.二叉树的最大路径和思路类似,使用深度优先搜索
- 注意要确定返回条件,所以计算的时候要算节点数量而不是关系数量,最后再-1
- 广度优先搜索
- 递归(深度优先搜索):自下而上递归
- 广度优先搜索:注意为叶节点时的判断边界
- 深度优先搜索:注意要传值
- 深度优先搜索:二分查找 (注意边界条件是left>right,没有=)
- 归并排序
- 迭代
- 递归
- 快速排序(链表的拼接很少见)
-
插入排序
- 从前往后找插入点
- pre 作为指针,在重新插入的时候发挥作用
- 动态规划
- 动态规划
- 动态规划省时间 滑动窗口省空间
- 滑动窗口
- 想象两把尺子,错开之后比较相同的部分,找最长相同的串就好了。
- 求每种颜色数量再返回
- 类似练习里OnSortArray的思路,单指针进行交换
- 双指针一步到位
- 快慢指针
- KMP 算法
- KMP 算法
- KMP算法
- Floyd算法
- Dijkstra算法
- 深度优先搜索
- 广度优先搜索(BFS对于求最短优于DFS)
- 广度优先和Dijkstra都要注意标注已访问
- 运算为中缀(中序遍历),转化为二叉树要知道前缀(前序遍历)
- 中缀表达式转前缀表达式
- 参考105:从前序与中序遍历序列构造二叉树
- 递归
- 强调了根节点到叶子节点,判断起来会方便一些
- 广度优先遍历
- 广度优先搜索
- 记录父子节点情况
- 深度优先搜索
- 注意 List 内部添加list的时候,要使用类似这样的表达
ans.add(new LinkedList<>(path));
- 注意 List 内部添加list的时候,要使用类似这样的表达
- 二分查找
- 如何弄清边界问题
- 当左边界要更新为
l = mid,r = mid-1
时,我们就令mid =(l + r + 1)/2
- 当右边界要更新为
r = mid,l = mid+1
时,我们就令mid =(l + r)/2
- 如何弄清边界问题
-
l+r >r+l
,通过字符串相加的方式可以比较两个字符串的大小- lambda排序
Arrays.sort(str,(x,y)->(x+y).compareTo(y+x));
- 快排 字符串自身也可以compareTo
- lambda排序
- lambda排序
Arrays.sort(str,(x,y)->(x+y).compareTo(y+x));
- 快排 字符串自身也可以compareTo
- 贪心算法
- 贪心算法
- 正向查找O(n)
- 反向查找O(n^2)
- 广度优先搜索
- 和迷宫问题一样,为了防止死循环,要有一个判断是否访问的标志
- HashMap存储前驱
- 优先队列实现最小堆
-
回溯算法
-
迭代法实现子集枚举
- 子集类型题目可以使用位运算
- 回溯算法
- 回溯算法
- 注意可以用HashSet去重,不过会超时
- 简便的方法是由于重复的会在回溯的第一阶段就计算,因此指针指向第二个及以后的时候进行顺延
- 标记字母和次数进行相加
- 注意字符串不能直接反转,可以转换成StringBuffer再反转
- 快慢指针
- 写的慢指针要从头开始,这样才能避免出现偏差
- 邻接条件很多很烦
- 用列竖式很麻烦,很容易错
-
num1[i]
和num2[j]
的乘积对应的就是res[i+j]
和res[i+j+1]
这两个位置。
-
- 前缀和处理区间问题
- 使用HashMap优化
- 动态规划
- 考察空间复杂度的优化
- 优化一:由于
dp[i][j] = dp[i-1][j] + dp[i][j-1]
,因此只需要保留当前行与上一行的数据 (在动态方程中,即pre[j] = dp[i-1][j]
),两行,空间复杂度O(2n); - 优化二:
cur[j] += cur[j-1]
, 即cur[j] = cur[j] + cur[j-1]
等价于思路二cur[j] = pre[j] + cur[j-1]
,因此空间复杂度为O(n)
- 优化一:由于
- 动态规划
- 双指针
- 位运算(异或满足交换律和结合律)
- 排序求中值
- 哈希表
- 投票算法(核心是对拼消耗)
- 横向扫描
- 纵向扫描
- 倒序遍历
- 寻找最大值
- 线性搜索
- 二分搜索
- 要注意题目条件,在题目描述中出现了
nums[-1] = nums[n] = -∞
,这就代表着 只要数组中存在一个元素比相邻元素大,那么沿着它一定可以找到一个峰值
- 要注意题目条件,在题目描述中出现了
- 动态规划
- 单调栈
- 双指针
- 注意不超出范围的判断
- 正数和负数怎样算
- 顺序合并
- 归并合并
- 优先队列(注意链表的空间变化)
- 埃式筛
- 哈希表
- hashmap.getOrDefault
- 回溯算法+深度优先遍历
- 回溯算法要注意先剪枝
- 泛型括号内设定空间大小可降低占用空间
- 水平翻转+对角线翻转
- 回溯算法+深度优先遍历
- 判断具体的返回条件
- 二分查找
- 比较前只考虑最右的特殊情况,是因为我们只需要在二分中找到大于等于target值的最小值
- 二分查找
- 二分查找
- 比较的对象要注意
- 模拟
- 哈希表查找的时间复杂度为O(1),因此考虑使用哈希表查找连续的数字。
-
动态规划
dp[row + 1][col + 1] = Math.min(Math.min(dp[row + 1][col], dp[row][col + 1]), dp[row][col]) + 1;
-
分治法
- split("",-1)处理多个重复
IP.chars().filter(ch -> ch == '.').count() == 3 //计算字符串中字符的数量
Character.isDigit(ch)
- 栈处理符号* 、/
- 栈处理+、-
- 动态规划
- 栈
- 滑动窗口
Iterator iterator = orient.entrySet().iterator();
while(iterator.hasNext){
Map.Entry entry = (Map.Entry)iterator.next();
Character key = (Character)entry.getKey();
Integer value = (Integer)entry.getValue();
}
- 两次二分查找
- 一次二分查找
- 模拟
- 二分
- 数组实现哈希
- 贪心 + 单调栈
sb.deleteCharAt(i)
s.indexOf(stack.peek(), i) > 0
- 单调栈
- 单调栈
- 中序遍历
- 滑动窗口+有序窗口
- 滑动窗口+单调队列
- 数学
- 最小堆
- 动态规划
- 哈希表
- 栈
- 动态规划
- 动态规划
- 广度优先搜索
- 要考虑溢出的问题
- 暴力
- 迭代逆推
- 递归
- 广度优先搜索
- 前缀和+二分查找
- 滑动窗口
- 双指针
- 筛选 + 判断
- 在原字符串上直接判断
- 栈
- 反转一半数字
- 环形替换
- 数组反转
- 回溯算法
- 模拟
- 拓扑排序(本质是广度优先搜索和贪心算法在图中的应用)
- Set
- 排序+双指针
- 两次遍历
- 参考题143,将数组看作一个循环链表
- 迭代
- 递归
- 模拟
- 递归
- 迭代
- 动态规划(跳楼梯)
- 模拟
- 最大公约数
- System.arraycopy(src, srcPos, dest, destPos, length);
- Object src : 原数组
- int srcPos : 从元数据的起始位置开始
- Object dest : 目标数组
- int destPos : 目标数组的开始起始位置
- int length : 要copy的数组的长度
- 4点构成的6条直线,存在相等或倍数上的关系
- 正方形中任意三点均可构成等腰直角三角形
- 考虑给出坐标重合的情况