数组篇5题
循环不变量原则,坚持对区间的定义,确定好边界的范围
通过一个快指针和慢指针在一个for循环下完成两个for循环的工作
滑动窗口也算是一种双指针
链表篇7题
有了虚拟头节点就对链表的增删操作统一了
也用到了虚拟头节点,方便增删改的操作
递归法和迭代法(双指针)
虚拟头节点
虚拟头节点+快慢指针
双指针
找环,但要设计一些数学证明
哈希表8题
什么时候用哈希表?给你一个元素判断在这个集合里是否出现过
一般来说哈希表都是用来快速判断一个元素是否出现集合里。
数组大小是受限的
数组大小没有限制,避免浪费就用Set做映射了
map是一种
的结构,本题可以用key保存数值,用value在保存数值所在的下标。所以使用map最为合适
字符串7题
字符串的题型常客
剑指Offer 05.替换空格
剑指Offer 58-II.左旋转字符串
KMP的主要思想是当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了。
栈与队列7题
单调队列
优先级队列
二叉树31题
基本都是可递归可迭代
递归法三部曲:
迭代法
深度优先遍历:
三种排序都可以通过递归实现
前序后续可以通过递归、通过栈实现递归解决,但中序遍历用栈实现递归的话要做标记
广度优先遍历:
通过队列模拟
递归:后序,比较的是根节点的左子树与右子树是不是相互翻转
迭代:使用队列/栈将两个节点顺序放入容器中进行比较
递归:后序,求根节点最大高度就是最大深度,通过递归函数的返回值做计算树的高度
迭代:层序遍历
递归:后序,求根节点最小高度就是最小深度,注意最小深度的定义
迭代:层序遍历
递归:后序,通过递归函数的返回值计算节点数量
迭代:层序遍历
递归:后序,注意后序求高度和前序求深度,递归过程判断高度差
迭代:效率很低,不推荐
递归:前序,方便让父节点指向子节点,涉及回溯处理根节点到叶子的所有路径
迭代:一个栈模拟递归,一个栈来存放对应的遍历路径
递归:后序,必须三层约束条件,才能判断是否是左叶子。
迭代:直接模拟后序遍历
递归:顺序无所谓,优先左孩子搜索,同时找深度最大的叶子节点。
迭代:层序遍历找最后一行最左边
递归:顺序无所谓,递归函数返回值为bool类型是为了搜索一条边,没有返回值是搜索整棵树。
迭代:栈里元素不仅要记录节点指针,还要记录从头结点到该节点的路径数值总和
递归:前序,交换左右孩子
迭代:直接模拟前序遍历
递归:前序,重点在于找分割点,分左右区间构造
迭代:比较复杂,意义不大
递归:前序,分割点为数组最大值,分左右区间构造
迭代:比较复杂,意义不大
递归:前序,同时操作两个树的节点,注意合并的规则
迭代:使用队列,类似层序遍历
递归:二叉搜索树的递归是有方向的
迭代:因为有方向,所以迭代法很简单
递归:中序,相当于变成了判断一个序列是不是递增的
迭代:模拟中序,逻辑相同
递归:中序,双指针操作
迭代:模拟中序,逻辑相同
递归:中序,清空结果集的技巧,遍历一遍便可求众数集合
递归:中序,双指针操作累加
迭代:模拟中序,逻辑相同
递归:后序,回溯,找到左子树出现目标值,右子树节点目标值的节点。
迭代:不适合模拟回溯
递归:顺序无所谓,如果节点的数值在目标区间就是最近公共祖先
迭代:按序遍历
递归:顺序无所谓,通过递归函数返回值添加节点
迭代:按序遍历,需要记录插入父节点,这样才能做插入操作
递归:前序,想清楚删除非叶子节点的情况
迭代:有序遍历,较复杂
递归:前序,通过递归函数返回值删除节点
迭代:有序遍历,较复杂
递归:前序,数组中间节点分割
迭代:较复杂,通过三个队列来模拟
回溯算法12题
回溯三部曲:
回溯是递归的副产品,只要有递归就会有回溯
回溯法就是暴力搜索,并不是什么高效的算法,最多再剪枝一下
所有回溯问题都可以抽象成树形结构
for循环横向遍历,递归纵向遍历,回溯不断调整结果集
剪枝精髓是:for循环在寻找起点的时候要有一个范围,如果这个起点到集合终止之间的元素已经不够题目要求的k个元素了,就没有必要搜索了
在for循环上做剪枝操作是回溯法剪枝的常见套路
组合总和(一)
已选元素总和如果已经大于n(题中要求的和)了,那么往后遍历就没有意义了,直接剪掉
组合总和(二)
如果是多个集合取组合,各个集合之间相互不影响,那么就不用startIndex
本题还需要startIndex来控制for循环的起始位置
组合总和(三)
集合元素会有重复,但要求解集不能包含重复的组合。“树枝去重”和“树层去重”
用求解组合问题的思路来解决 切割问题本题就成功一大半了
但后续如何模拟切割线,如何终止,如何截取子串,其实都不好想,最后判断回文算是最简单的了
子集问题(一)
在树形结构中子集问题是要收集所有节点的结果,而组合问题是收集叶子节点的结果
子集问题(二)
多了去重
和子集很像
排列问题(一)
不同之处:
排列问题(二)
去重,“树层去重”和“树枝去重”
贪心算法16题
找出局部最优并可以推出全局最优
动态规划38题
动态规划五部曲:
01背包理论基础
01背包理论基础(滚动数组)
完全背包理论基础
多重背包理论基础
单调栈5题
一路走来,我是没想到自己真的坚持下来了哈哈哈,首先Carl哥讲的是真的好,很通透且清晰,从最开始的数组,到最后的单调栈,循序渐进,层层递进,一环扣一环,有些难题本来就不会做,没有前面的铺垫那就更加不会了,Carl哥用心了!
其实自己也不好说完全掌握了这一路走来做的所有题,毕竟本来几乎没什么算法基础,总结完以后,以后估计都得二刷三刷什么的,算法就是这样,练得少就不行。
数组的二分、双指针,链表的虚拟头节点、双指针,哈希表的数组、Set、Map,字符串的双指针、KMP,栈与队列的经典问题,二叉树的递归三部曲、遍历、属性、构造以及搜索树,回溯算法三部曲、组合、排列,贪心算法的局部推导全局,动态规划的五部曲,以及最后的单调栈收尾,这一切的学到的东西都让我收获满满,不少以前从来没听说过的,经过这60天的算法训练,让我一直不断提升,比前一天的自己更好,但不是说跟着Carl哥练完这60天,就变得无敌了,自己不努力改变,没人能替你成长。往后每天还是得不断坚持刷题,坚持巩固,也不祈求以后进个什么大厂,只要坚持以后,能达到我自己所能达到的级别即可。
problems/next-greater-element-ii/)
一路走来,我是没想到自己真的坚持下来了哈哈哈,首先Carl哥讲的是真的好,很通透且清晰,从最开始的数组,到最后的单调栈,循序渐进,层层递进,一环扣一环,有些难题本来就不会做,没有前面的铺垫那就更加不会了,Carl哥用心了!
其实自己也不好说完全掌握了这一路走来做的所有题,毕竟本来几乎没什么算法基础,总结完以后,以后估计都得二刷三刷什么的,算法就是这样,练得少就不行。
数组的二分、双指针,链表的虚拟头节点、双指针,哈希表的数组、Set、Map,字符串的双指针、KMP,栈与队列的经典问题,二叉树的递归三部曲、遍历、属性、构造以及搜索树,回溯算法三部曲、组合、排列,贪心算法的局部推导全局,动态规划的五部曲,以及最后的单调栈收尾,这一切的学到的东西都让我收获满满,不少以前从来没听说过的,经过这60天的算法训练,让我一直不断提升,比前一天的自己更好,但不是说跟着Carl哥练完这60天,就变得无敌了,自己不努力改变,没人能替你成长。往后每天还是得不断坚持刷题,坚持巩固,也不祈求以后进个什么大厂,只要坚持以后,能达到我自己所能达到的级别即可。
看似不起波澜的日复一日,一定会在某一天,让你看到坚持的意义。