第一周:
并查集:
面试题
1:简单利用并查集,因为每次输入的时间戳都是递增的,每次输入都对连通性做判断。当所有点连通时输出时间戳即可。
2:改造并查集方法,find(i)输出i所在并查集的最大值。新增一个数组用来标记最大值即可。
3:输出比x大的在S中的最小y。接第二题的思路,题目要求查找的是没有被remove的值里面大于x的最小值。将remove的值全部union,然后返回find(x)+1即可。
编程作业
渗透:使用蒙特卡洛估计法,找出使得第一行和最后一行连通的最小需要打开的格子数量。借助新增加的top和bottom节点,分别维护一个和top相连的并查集和一个与top和bottom都相连的并查集,isFull方法防止回流情况。
算法分析:
面试题
1:二次方时间内解决3-SUM问题。借助map数据结构记录数字即可。忽略构造map的时间(O(n)),计算两数和时间为O(n2)。以时间换空间
2:在双调数组中搜索,数组为先递增后递减。方法是先二分查找找出最大值,然后再左右各二分查找。3lg(n)。
3:扔鸡蛋问题。考察对各种数学模型的分析,例如等差,等比数列函数的近似函数。
第二周:
栈和队列:
面试题
1:用两个栈模拟队列。常见题目不赘述。
2:最大栈。借助一个新的栈只记录某一时刻栈的最大值,跟普通栈同时push和pop。
3:Java禁止泛型数组的原因。(依然没有透彻理解)
https://www.cnblogs.com/lsgxeva/p/10231538.html
https://wiyi.org/type-erasure.html
https://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super
A generic type is a type with formal type parameters. A parameterized type is an instantiation of a generic type with actual type arguments.
编程作业
实现Deque和RandomizedQueue。分别使用链表和数组实现,考察基础。
基础排序
面试题
1.两个集合取交集:通过set对point类去重,继承comparable定义比较器。
2.判断一个集合是否是另一个集合的排列:排序后按位比较。
3.荷兰国旗问题:3-way quicksort。分区间,三个flag,交换。经典问题。
第三周
归并排序
面试题
1.只用O(n)的空间复杂度,归并2n大小数组,0~n-1和n~2n-1已排好序。思路是先移走0~n-1,然后与后n个比较归并,结果放到2n大小数组内,比较巧妙。
2.计算逆序对。在归并排序基础上,子数组排好序后,归并的时候算逆序的个数。
3.将链表乱序。借鉴归并排序的思路,根据随机数随机选择一个归并。
编程作业
共线的点。感觉这道题很难,思路就是借助point类的api和specification的思路来做。巧妙之处在于需要先对点进行自然顺序的排序,然后指定每个点为原点后,再对剩下点与该点的斜率做一个排序,将斜率相同点全部加入结果队列中。并根据原点与斜率相同点的最小点(队列首)进行比较的方式,排除掉重复线段。
快速排序
面试题
1.匹配螺丝和螺母。用螺丝中选定的某一个对螺母进行分区,分区后再用螺母的对应值对螺丝进行分区。两堆都分区完毕后,再分别对两个子分区做相同操作。
2.两个有序数组中找第k大(小)数字,要求时间复杂度O(logN)。这道题可以扩展为n个有序数组中找第k大(小)数字。
以两个递增数组找第k小数为例,如果先归并排序然后再找,时间复杂度为O(NlogN)。采用的方法是每次删除其他一个数组中的k/2个数字,因为第k小的数一定不在这里面。直到k=1时找出两个数组中最小的数。如果在删除过程中发现哪一个数组数字不够用了,说明答案在另一个数组里面。
3.找出数组中出现次数大于1/10的数字。
采用3-way快排的方式,每次选出一个数,将比这个数小的交换到左侧,比这个数大的交换到右侧,判断这个数的个数是否大于1/10个数组长度。接下来再分别去对比这个数小的分区和比这个数大的分区做快排。
第四周
优先队列
面试题
1.动态中位数。要求O(1)的时间复杂度得到中位数,新加入数字和删除中位数的时间复杂度为O(logN),很明显需要堆作为基础的数据结构,但最大堆和最小堆都只能维护最大值和最小值,最后考虑是使用一个最大堆和一个最小堆,并维持两个堆的长度之差不超过1来维持中位数。
2.随机优先队列。使用随机数生成数组的第n个数字返回即可,删除时将最后一个数与该数进行交换,并重新构建堆。
3.出租车牌数字。如果是要求空间复杂度O(n2),则构造一个二维数组存不大于n的数字的立方和,接下来做归并排序,找出其中相等的数字即可。如果要求使用空间更少,只使用O(n)的空间复杂度,则我们在逻辑上使用二维数组存立方和,但是在遍历的时候使用最大堆来维护最大值,比较前后两个最大值是否相同来得到结果。利用了逻辑上二维数组下比上大,右比左大的特性来遍历。
编程题
8-puzzle问题。得充分读懂题意,采用specification里面的思路来编程。构造树的gameNode结点,并利用最小堆来维护优先级最高的node。还需要注意剪枝(交换后等于上上个node的情况),以及不可解的判断(twin和原来的node只会有一个有解)。
基础符号表
面试题
1.Java装箱和equals. 通过这道题明白了看源码的有用之处.double类的源码注释已经列出了答案
2.检查一棵树是否为二叉搜索树. 可以通过递归来实现中序遍历,并保存上一个值,比较上一个与这一个值的大小来判断是否为二叉搜索树. 也可以通过栈来实现.
3.用常数空间来实现中序遍历. 一般都是使用Morris遍历方式.
4.用户网站访问记录的实现, 要求提供两个API,一个是用户访问了一次网站.一个是某用户访问了网站多少次. 实现方式可以为使用hashmap,用户作为key,value是另一个hashmap,其中key为网站,value为访问次数
第五周
平衡搜索树
1.不需要额外空间记录颜色的红黑树实现方式. 没思路
2.文档搜索: 题意不太理解
3.泛化队列:使用红黑树,插入时的索引记为key,最小值即为队首,最大值即为队尾.
二叉搜索树的地理应用