81、最大正方形
牛客 108 最大正方形:
思路:
- 定义二维数组dp[m][n],其中dp[i][j]表示的是在矩阵中以坐标(i,j)为右下角的最大正方形边长。
- dp[i][j] = Math.min(dp[i – 1][j], Math.min(dp[i – 1][j – 1], dp[i][j – 1])) + 1;
82、旋转数组
牛客 110 旋转数组
思路:
- 整体反转,再反转前半部分,再反转后半部分
83、数据流中的中位数
牛客 131 数据流中的中位数
思路:
- 插入排序
84、连续子数组最大乘积
牛客 83 连续子数组的最大乘积:
85、把数字翻译成字符串
牛客 116 把数字翻译成字符串:
思路:
- 用辅助数组dp表示前i个数的译码方法有多少种
- 注意 10 和 20 的特殊处理
86、二叉树的镜像
牛客 72 二叉树的镜像:
思路:
- 后续遍历,调换左右节点
87、相同的子树
牛客 98 判断t1树中是否有与t2树完全相同的子树:
思路:
- 先序遍历序列化,然后包含匹配
88、调整数组顺序使奇数位于偶数前面(一)
牛客 77 调整数组顺序使奇数位于偶数前面(一):
思路:
- 遍历统计奇数个数,锁定偶数指针,双指针一路向前
89、合并二叉树
牛客 117 合并二叉树:
思路:
- 前序遍历,new 新的根节点承接和,并设置左右子树
90、扑克牌顺子
牛客 63 扑克牌顺子:
思路:
- max-min<5,且无重复
91、分隔链表
力扣 86 分隔链表:
思路:
- 把原链表一分为二,分成两个小链表,最后接在一起。
92、数组不可变
力扣 303 区域和检索 – 数组不可变:
思路:
- 标准的前缀和问题,核心思路是用一个新的数组 preSum 记录 nums[0..i-1] 的累加和
- 有了 preSum 数组,如果我想求索引区间 [1, 4] 内的所有元素之和,就可以通过 preSum[5] – preSum[1] 得出
- 这样,sumRange 函数仅仅需要做一次减法运算,避免了每次进行 for 循环调用,最坏时间复杂度为常数 O(1)。
93、字符串的排列
力扣 567 字符串的排列:
思路:
- 滑动窗口
94、二叉搜索树中第 K 小的元素
力扣 230 二叉搜索树中第 K 小的元素
思路:
- BST 的中序遍历结果是有序的(升序),所以用一个外部变量记录中序遍历结果第 k 个元素即是第 k 小的元素。
95、矩阵不可变
力扣 304 二维区域和检索 – 矩阵不可变
思路:

- 如果我想计算红色的这个子矩阵的元素之和,可以用绿色矩阵减去蓝色矩阵减去橙色矩阵最后加上粉色矩阵,而绿蓝橙粉这四个矩阵有一个共同的特点,就是左上角就是 (0, 0) 原点。
- 那么我们可以维护一个二维 preSum 数组,专门记录以原点为顶点的矩阵的元素之和,就可以用几次加减运算算出任何一个子矩阵的元素和。
96、编辑距离
力扣 72 编辑距离
思路:
- 如果使用自底向上的迭代解法,这样定义 dp 数组:dp[i-1][j-1] 存储 s1[0..i] 和 s2[0..j] 的最小编辑距离。dp 数组索引至少是 0,所以索引会偏移一位。
【迭代解法】
【递归解法】

