前言
我们把自己做的算法题进行归类总结,进行一个目录导航
算法不是一个速成的东西,算法就像做数学题,各种题型在一个根题型的基础上进行变化。
我的学习方法
写文章 ---- 为啥要写文章?因为算法题目太多,2千多道题目,你不可能都记得住。就算你现在记住了,后面也会忘的。所以一定要写文章,后面的话方便快速复习。而且写文章也能检测你是否真正掌握了这个题目,如果你没有真正掌握,那么你也写不出来,每篇文章不能少于600字
总结模板 ---- 就算你第一遍掌握了,那么这么多道题,你还是会忘,所以我们要找到这些题目中共性的东西总结出来,总结不出来,说明你还是没学会。
同一道题最少做5遍 ---- 第一遍你可能懵懵懂懂,然后你写了文章。第二遍,你总结了模板,印象加深了。第三遍,把模板进行了丰富,有所掌握。第四遍,题目做的快了很多。第五遍,完全掌握。我说的这些只是参考,以实际为准。
我们要达成的效果就是一道题目能在5分钟内写出来,并且准确率能有100%,高级一点的话,能用两种方法写出来
所有的题目第一步上来是判断给的参数
数组和字符串
双指针解法(数组必须有序)
解析: 前提是必须先排序
js算法题解(第二天)---LeetCode:88.合并两个有序数组
js算法题解(第四天)---LeetCode:11 盛最多水的容器
注意理解题意:取短的那根板
js算法题解(第五天)---LeetCode:344.反转字符串和 125. 验证回文串
# js算法题解(第六天)---LeetCode:680. 验证回文字符串 Ⅱ和28.实现 strStr()
像这种查找回文串和strStr都重新再定义一个函数,可以让代码变得清晰
下标法
js算法题解(第三天)---LeetCode:283.移动零和15. 三数之和 - 掘金 (juejin.cn)
中心扩散法(专门用于找回文子串的)
js算法题解(第七天)---LeetCode: 5.最长回文子串 - 掘金 (juejin.cn)* 思路:遍历每一个索引,以这个索引为中心,利用“回文串”中心对称的特点,往两边扩散,看最多能扩散多远。
模板
var centerSpread = (str, left, right) => { // 双指针判断条件 while (left >= 0 && right < str.length) { if (str[left] === str[right]) { left--; right++; } else { break; } } return str.substring(left + 1, right);};
哈希法
解析:最快的查询方法
js算法题解(第一天)---LeetCode:1.两数之和
几乎所有的求和问题都可以用求差问题来解决
只要是查找最快的方法,立马想到哈希表
链表
定义头结点(只要是需要操作第一个节点的,都需要使用头结点)
模板
if(!head||!head.next){ return head;}let dummy = new ListNode();dummy.next = head;let cur = dummy;while(cur){ if(){ // 主要代码部分 }else{ // 循环链表必写代码 cur = cur.next; }}return dummy.next;
判断条件主要看子作用域中如何使用的 例如 |子作用域| 判断条件| |-|-| |cur.val |cur| |cur.next.val |cur&&cur.next| |cur.next.next.val|cur&&cur.next&&cur.next.next|
子里面使用几个next
,那么父就要判断
几个next
js算法题解(第十天)---LeetCode:82. 删除排序链表中的重复元素 II
js算法题解(第九天)---LeetCode:83.删除排序链表中的重复元素
js算法题解(第八天)---LeetCode: 21. 合并两个有序链表
删除链表
cur.next = cur.next.next;
快慢指针
js算法题解(第十一天)---LeetCode:19. 删除链表的倒数第 N 个结点
快指针在前面走,慢指针在后面追他
模板
let dummy = new ListNode(); dummy.next = head; let quick = dummy; let slow = dummy; let count = 0; while(quick){ if(count>n){ slow = slow.next; } quick = quick.next; count++; }
多指针
js算法题解(第十二天)---206. 反转链表(3个指针)
专门用于链表反转
定义好pre,cur,next三个指针
模板
// 注意初始pre必须是null,因为他是反转后的最后一个元素 let pre = null; let cur = dummy.next; while(cur){ // next不能写到外面,如果cur为null的话,那么cur.next就报错了 let next = cur.next; }
js算法题解(第十三天)---92. 反转链表 II(4个指针)
会给你left(开始反转的节点),right(结束反转的节点) 所以要有两个循环,一个循环到left,一个循环到right
环
设立flag
head.flag = true;
栈
对称性
js算法题解(第十五天)---20. 有效的括号 - 掘金 (juejin.cn)
辅助栈
js算法题解(第十六天)---155. 最小栈 - 掘金 (juejin.cn)
求最小值用升序,求最大值用降序
此题的注意点就是pop的时候会把当前的最小值的数字pop掉
队列
八字转换
js算法题解(第十七天)---225. 用队列实现栈
辅助队列
js算法题解(第十八天)----剑指 Offer 59 - II. 队列的最大值和239. 滑动窗口最大值
求最小值用升序,求最大值用降序
树
广度优先遍历(BFS模板)
function BFS(入口坐标) { const queue = [] // 初始化队列queue // 入口坐标首先入队 queue.push(入口坐标) // 入口坐标是第一层也就是0,所以level从1开始,代表遍历第二层 let level = 1; // 队列不为空,说明没有遍历完全 while(queue.length) { // 当前queue的长度,一定要先声明长度,因为queue一直在变 let length = queue.length; // for循环使当前层的都出列,下一层的都入列 for(let i=0;i<length;i++){ // 上面的i不要用,因为我们 let node = queue.shift(); // 从node上取出元素,放到queue队列中 queue.push(取出的元素) } // 层数+1; level++; }}
js算法题解(第十九天)---LeetCode:102. 二叉树的层序遍历
回溯算法
要使用回溯算法,那么需要搞清三个东西
1.路径(track):也就是已经做出的选择
2.选择列表(nums):也就是你当前可以做的选择
3.结束条件:也就是无法在做选择的条件
并记住下面这两张图
result = [];let backTrack = function(选择列表,路径){ if(满足条件){ result.push(路径); return; } for(选择 in 选择列表){ 添加到路径中 backTrack(选择列表,路径) 从路径中撤销 }}
js算法题解(第二十天)---leetcode-46. 全排列
二叉树遍历
js算法题解(第二十二天)---144.二叉树的前序遍历
深度优先遍历(dfs模板)
const dfs = function(root){ // 递归结束条件 if(!root){ return 0; } let left = dfs(root.left); let right = dfs(root.right); // 逆想思维求高度 return Math.max(left,right)+1; }
js算法题解(第二十五天)---110. 平衡二叉树
递归
226. 翻转二叉树
101. 对称二叉树
二分查找
搜索一个元素
搜索一个元素时,搜索区间两端闭。
\ while条件带等号,否则需要打补丁。
\ if相等就返回,其他的事甭操心。
\ mid必须加减一,因为区间两端闭。
\ while结束就凉凉,凄凄惨惨返-1。
ts算法题解(第35天)----leetcode 704. 二分查找
搜索多个元素
搜索左右区间时,搜索区间要阐明。
\ if相等别返回,利用mid锁边界。
\ while结束不算完,因为你还没返回。
\ 索引可能出边界,if检查保平安。