持续更新中...
陆续刷过一部分Leetcode的题目,但是并没有形成体系化的一个结构,盲目刷题其实效果一般。通过归类汇总会更有助于记忆,刚好趁这个机会梳理一下之前做过的题的思路,并不会有详细的代码,主要是思路的梳理和思考过程的体现。
目前还在梳理阶段,会慢慢列一些提纲和补全
基本分类
- 基本数据结构
- 数组
- 队列和栈
- 链表
- 二叉树
- hash
- 堆
- 常见的算法
- DFS
- BFS
- 双指针
- 回溯
- 动态规划
- 贪心
- 排序
- 二分查找
🐙哈希表 空间换时间
常见题目类型
- 查找:通过预遍历一遍将数据存储到map,减少二次查询成本
相关题目
两数之和 n
通过map用空间换时间,在循环过程中将值和index存到map表里。
🐙双指针
常见题目类型
- 数组相关
- 链表相关
相关题目
三数之和 n2
- 先排序(时间复杂度n log n < n2,所以可接受)
- 排序好之后从0开始遍历一遍(n2)
- 如果当前位置i的值>0,说明之后无法=0,直接结束循环。
- 从当前位置的下一位开始,设置左指针(i+1),以及右指针(放在数组末尾)
- 然后操作L 和 R,直到他们相遇。具体操作规则如下:
- 如果L+R+nums[I]<0,把L++
- 如果>0,把R--
- 如果 = 的话,把他们放进结果集,然后处理相邻数据相等的情况
盛最多水的容器
- 原理是:要移动数字较小的那个指针,然后动态更新max值
无重复字符的最长字串
- 解法:滑动窗口法,从0开始遍历一次
- 遇到未出现过的字符,push到结果数组里,然后更新max最大长度
- 遇到出现过的字符,把结果数组从首次出现的位置的下一个,进行截断,然后更新最大长度
删除链表的倒数第n个节点
- 解法:设置一个间隔为n的快慢指针
旋转链表
- 解法:间隔为n的快慢指针,将结尾节点指向head,慢指针指向空
合并有序数组
🐙二分查找
解题框架
var searchInsert = function(nums, target) {
let left = 0;
right = nums.length - 1;
while (left <= right) {
let mid = Math.round((left + right) / 2); // or (left + right) >>> 1
if (target === nums[mid]) {
return mid;
} else if (target < nums[mid]) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return left;
};
相关题目
搜索旋转排序数组
- start=0,end=len-1,找出mid 的值和target的关系,找到target所处的那个区间,修改start/end,继续二分
- 结束循环:start= end,或者找到了start/mid/end = target的位置
🐙回溯法
解题框架
let result = []
function backtrack(路径, 选择列表) {
if (满足结束条件)
result.add(路径)
return
for 选择 in 选择列表
做选择
backtrack(路径, 选择列表)
撤销选择
}