终于刷完了。。。。。虽然是暑假,但是也有点不容易。收获很大!
数组
主要是双指针法和二分查找,双指针法一种是快慢指针,另一种是从两边开始往中间走。除此之外快慢指针还可以检查链表中是否出现环。关于二分法,最主要的就是边界问题,要想好左右边界,有时候会有无法取到的问题。然后就是mid的值的计算方式也有一些不同的方法。
链表
链表的处理,有时候加上头结点处理起来会方便很多。因为如果把链表接在头结点后面,那么第一个值就在第二个结点中,不需要考虑头指针的特殊情况。所以一般都会加头结点。然后就是改变链表间元素的相互顺序或者先后顺序,主要是靠next指针决定的,p->next=p->next->next就是跳过下一个结点。。。相同的原理还可以用来反转链表,可以用一个temp指针暂时存储指向的结点。然后还有成环链表,之类的,一般都会转化为数学问题。
哈希表
一般用来查找东西,或者是一个东西的具有的特殊值。如果每个元素对应的值都不一样,那么输入这个元素对应的下标可以直接返回他对应的值。时间复杂度是o(1),如果使用常规的遍历可能会达到o(n)的复杂度。除此之外还可以验证一个元素是否出现过,给元素赋初值,如果出现了这个元素,那么改变该元素对应键值对的值,当第二次相同的元素被访问到时就会发发现键值对发生了改变,这样就可以判断一个数字是否出现过。
字符串
vector<char>和string基本没有什么区别,相比于vector,string重载了+号,可以实现两个字符串直接相加。针对vector,有front(), back(), size(), resize(), push_back(), pop_back(), insert(), sort, reverse(), find(),其中一些依靠迭代器实现。
栈与队列
感觉重点是这两种容器的操作方法。stack:push()压入栈中, pop()弹出栈, top()栈顶元素, empty()判断栈空。queue:push()入队, pop()出队,empty()判断队列是否为空, size()队列内元素数量,front()队头元素, back()队尾元素。除此之外还有双向队列,两头都能插入弹出。另一个是要记住栈和队列的区别。栈是先进后出,队列是先进先出。
二叉树
有基本的构造操作,前序中序后序层次遍历。中序遍历+前序/后序都可以确定唯一一棵树。前中后序遍历其实也是递归遍历,在每一层中可以考虑回溯的问题,如果需要原值就回溯,改变后的值就不回溯。二叉搜索树,也叫二叉排序树左孩子节点的值小于根节点的值,右孩子结点的值大于根节点的值,二叉搜索树的中序遍历的值是从小到大有序的。
回溯算法
深度优先是递归实现的,回溯算法也算是深度优先。递归>深度优先>回溯。回溯一般可以用于路径的搜索,把所有路径放入答案数组,访问的一个终点时需要发生回退,同时在这一层进行的操作也应该复原,比如说元素弹出。回溯相对于深度优先只是多了一个撤销的操作,本质上也是深度优先。
贪心算法
本质是局部最优推导全局最优。没有具体的套路....每个题都算是不一样的方法,但是离不开贪心的思想。如果每一个阶段都能找到他的最优解,那么把这些最优解加在一起,就是整个问题的最优解。所以记住局部最优推出全局最优就可以了。局部最优推出全局最优。贪心四步:将几个问题分解为若干个子问题,找出每个问题的最优解,将局部最优解堆叠为全局最优解。
动态规划
简称DP,每一个状态都可以被前面的状态推导出来,典型的是爬楼梯和斐波那契数列。动态规划的递推公式很重要,但是有时候初始化和遍历顺序更重要。动规五部曲:1.确定dp数组及其下标的含义,2.确定递推公式,3.初始化,4.确定遍历顺序,5.打印dp数组。先找递推公式再考虑初始化,因为不找到递推公式就不知道前一个状态是什么,就不知道应该把哪个状态作为初始状态。debug方法:打印dp数组。
单调栈
分为单调递增栈和单调递减栈,拿单调递增栈举例,指的是从栈头到栈尾元素逐渐增加的栈。如果想要找到数组中一个数组中每个数右边第一个比他大的元素,那么碰到比他小的元素就入栈,比他大那么就存储这个元素,然后栈头元素出栈,当前元素入栈。直到遍历结束。单调递减栈刚好相反。
图论
涉及了深搜和广搜、并查集、最小生成树和最短路径问题。关于深搜和广搜的区别,广搜是一圈一圈搜,深搜是逮住一个方向搜,搜到头再回来换方向。深搜是递归,广搜是迭代。并查集是区分两个元素是否在一个集合里和将两个元素加入同一个集合,在进行这两个操作时会发生路径压缩,不断更新他们的根,根相同则属于同一个集合。最小生成树问题有prim算法和kruskal算法。prim算法是从点的角度考虑,判断最小权值。遍历所有点,寻找未遍历的点中距离生成树距离最短的点然后把这个点加入生成树,更新所有点与生成树的距离,然后继续遍历下一个点。kruskal算法则是从边的角度考虑,每次把长度最小的边纳入最小生成树,直到所有点都被连接,期间不能出现环。