个人 LeetCode 题解,用图片的形式展示解题思路。
哈希表
- 1. 两数之和:使用哈希表的 contains() 来比较其他元素是否符合条件,避免一一比较
- 136. Single Number:判断是否在 Set 中,在则删除,不在则添加,Set contains() 的时间复杂度为 O(1)
双指针
- 4. Median of Two Sorted Arrays:使用双指针,依次比较元素大小,小的加入到合并数组。
- 11. Container With Most Water:左右指针向中间遍历,大的固定,小的移动。最大的将始终固定。
- 26. 删除排序数组中的重复项:找到后面不重复元素(判断条件:当前元素和上一个元素是否相等),依次覆盖前面的元素,标签:
快慢指针
- 27. 移除元素:不删除,只覆盖。相向(拷贝)覆盖:后面的非目标值覆盖前面的目标值,标签:
同向(快慢)双指针
。相向(拷贝)覆盖:右边的所有值(包含目标值)覆盖左边的目标值,标签:相向(左右)双指针
- 88. 合并两个有序数组:比较得到两个数组最大的元素,作为最大值放在最后。
- 905. 按奇偶排序数组:将后面的偶数跟前面的奇数交换。标签:
前后双指针
三指针
- 15. 3Sum:先排序,3 数之和转换为 2 数之和,i 始终为负,左右指针向内遍历得到结果
- 16. 3Sum Closest:使用 diff 存放 target 和 sum 的差
二分查找
栈
- 56. 合并区间:先排序,再利用栈
双重循环
- 118. 杨辉三角:a2[1] = a1[0] + a1[1]
一次遍历
- 121. 买卖股票的最佳时机:只记录前面最小值
- 122. Best Time to Buy and Sell Stock II:降价前卖出即可
其他
- 35. 搜索插入位置:相当于返回目标值插入有序数组的位置,最直接的方式就是跟每一个元素比较
- 53. 最大子序和:需要记录到当前值的最大连续和;正数增益:当前值加上一个正数才大于当前值。标签:
正数增益
- 54. 螺旋矩阵:四边有栏,栏往里缩
- 66. 加一:从后往前遍历加 1,考虑 99->100
假节点
- 2. 两数相加:使用一个假节点来链接链表
- 83. 删除排序链表中的重复元素:若重复,指向下下个节点
指针
- 24. 两两交换链表中的节点:25 题,k 固定为 2 的场景
- 25. K 个一组翻转链表:分为已翻转、待翻转、未翻转,利用「指针」,分离原链表
双指针
- 141. 环形链表:有环:快指针跳两步,慢指针跳一步,两者总会相遇,标签:
快慢指针
假节点 + 双指针
- 19. 删除链表的倒数第 N 个节点:用一把长度为 N 的「尺子」,往右移动,右边到达末尾,左边就是倒数第 N 个节点。
递归
- 21. 合并两个有序链表:从最小的节点开始,将剩下的链表节点看成一个节点;递归找出剩下节点的最小节点。
其他
- 237. 删除链表中的节点:将下一个节点赋给当前节点,删除下一个节点。标签:
下一个节点
- 328. 奇偶链表:数组下标
- 7. 整数反转:依次除 10 取余,考虑溢出
- 9. 回文数:从两头向中间依次比较左数和右数是否相等
- 12. Integer To Roman:考虑 6 种特殊情况,从大到小循环取余
哈希表
- 13. 罗马数字转整数:IV=4 等 6 种特殊情况总结为一种:左边数比右边数小。减去当前值
二分查找
- 69. x 的平方根:如果
n^2 <= x && (n+1)^2 > x
那么 n 就是平方根
Sliding Window(滑动窗口)
- 3. 无重复字符的最长子串:滑动找到所有不重复的子字符串,如果子串长度最长,记录为最长子串。
数组
- 6. Z 字形变换:找到 x 坐标,坐标相同的放在一起,作为一个元素
动态规划:Dynamic programming,简称 DP。通过子问题解决父问题,即父问题答案可以通过子问题得到。
- 5. 最长回文子串:先将字符串反转,两者比较,利用动态规划得到最长公共子串。再排除字符串首尾是反向副本的情况(
aacdcaa
) - 91. 解码方法:从后往前遍历,当前子序列的和(解码方法数)跟上一个和上上个子序列的和相关
栈
双指针
- 28. 实现 strStr():将 needle(目标字符串) 依次与字符串 haystack 长度为 needle 的子串比较,完全相同则返回子串的数组下标。
- 151. 颠倒字符串中的单词:利用双指针和字典,将每个单词的第一个字符和最后一个字符位置对应关系保存
其他
- 14. 最长公共前缀:依次比较每个字符串的每一个字符
- 58. 最后一个单词的长度:反转字符串,如果长度 length 为 0,则代表最后字符为空,继续循环
- 67. 二进制求和:可转换为 10 进制求和,再转换为二进制
- 344. Reverse String:前后交换,但只需要交换一半即可
它既有链表的快速插入与删除操作的特点,又有数组快速查找的优势
递归 or 栈(深度优先遍历)
- 94. 二叉树的中序遍历:递归:左根右,如果没有左子树,记录其值。
- 100. 相同的树:利用递归,依次判断两个树的每一个节点的值是否相同。左左比较、右右比较
- 101. 对称二叉树:利用递归,依次判断对称节点的值是否相同。左右比较、右左比较
- 104. 二叉树的最大深度:递归:树的最大深度等于当前节点深度 1 加左右子树最大深度
- 108. 将有序数组转换为二叉搜索树:选择中位数作为根节点,再在左右两边选择一个中位数作为左右子树的根节点
- 110. 平衡二叉树:通过高度差判断,可以从上往下、也可从下往上
- 111. 二叉树的最小深度:需特殊考虑
[1,2]
的情况 - 112. 路径总和:如果到达叶子节点,并 sum - root.val == 0,则符合
- 144. 二叉树的前序遍历:递归:根左右,先记录其值,再递归调用左右子树。栈:入栈:节点不为空;出栈:节点为空
队列(广度优先遍历)
- 107. 二叉树的层次遍历 II:队列存放节点
辅助栈
- 155. 最小栈:栈存放正常元素,辅助栈存放最小元素。第一个元素为最小元素,如果后面比它小,入「小栈」,否则入「正常栈」
- 232. 用栈实现队列:使用两个栈,栈 s1 作为数据存储,辅助栈 s2 作为临时缓冲。
- 175. 组合两个表:LEFT JOIN * ON *
- 184. Department Highest Salary:使用 Group By + MAX()
当前运算依赖上一个运算的结果
- 70. 爬楼梯:需要找到规律
两个难点:
- 整体思路
- 将思路转换为代码
LeetCode 题库地址:https://leetcode-cn.com/problemset/all/
深度优先搜索(深度优先遍历) Depth-First-Search,简称 DFS,递归(栈)实现
宽度优先搜索(广度优先遍历)Breadth-First-Search,简称 BFS,队列实现