1.二叉查找树
左子树小于子根节点,右子树大于子根节点,减可变规模范例:若等于子根节点则结束,小于则在左边查找,大于则在右边查找
特殊情况:二叉查找树是严重倾斜的,全在左侧或者全在右侧
2.单堆拈游戏
单堆:
设置每次可以拿走的数量上限为m
败局:m+1的整数倍
面对的 1 <= n <= m直接可以拿走,同理m+2 <= n <= 2m+1拿掉1~m个使对方面对m+1的败局
归纳总结为n mod m+1 != 0时候为胜局,每次必须拿走n mod m+1个棋子
多堆:
n1 = x ,n2 = y,n3 = z
x y z分别用二进制表示,然后加和(不进位),当结果中存在大于等于1个1的时候为胜局,否则为败局
如果结果包含1,为了使结果只包含0,拿走的堆其中的数量需要按照使二进制加和变为0的结果即可
分治法
T(n) = aT(n/b) + f(n)
T(n)为问题规模,将问题规模分为b个,每个为n/b,有a个实例需要解,f(n)为拆分问题和合并问题所需要的运算规模
f(n)∈O(pow(n,d))
主定理:
T(n) = O(pow(n,d)) a < pow(b,d)
T(n) = O(pow(n,d) * log n) a = pow(b,d)
T(n) = O(pow(n,logb(a)) a > pow(b,d)
1.合并排序:
核心思想:
拆分折半B C
合并B C -> A
B C合并成A过程:i j k比较Bi Cj Ak = 小的那个然后对小的那个数组+1,循环直到i = p或j = q 然后把剩下的直接从k往后插插完为止
2.快速排序:
不同于lamuto算法,取标杆,小的一组,大的一组,标杆放在该放的位置,对小的那组和大的那组递归。
快排是取标杆,然后从左向右找大于标杆的i,从右向左找小于标杆的j,i<j时候交换,然后继续,直到i >= j,标杆和i交换
然后对标杆左侧和标杆右侧递归进行快排
3.树的遍历(对应的都是根)
前序遍历:先根再左后右
中序遍历:先左后根再右
后序遍历:先左后右再根
4.大整数乘法
核心思想:
有a 和 b 两个n位数
对半拆分a a1 a0
c = (a1 * pow(10,n/2) + a0 ) * (b1 * pow(10,n/2) + b0)
= a1 * b1 * pow(10,n) + (a1 * b0 + a0 * b1) * pow(10,n/2) + a0 * b0
5.strassen矩阵乘法
核心思想:
A B矩阵相乘(A B为nxn的矩阵,如果n不是2的乘方,则用0补齐)
将A B矩阵均划分为n/2 n/2的4个小矩阵,直到划分到可以计算为止。
6.最近对问题
先根据x坐标排序得P
P对半分PR PT d = min(dPR,dPT) 递归得到dPR dPT
但是d不一定是最近的距离,在中轴线左侧d长度,右侧d长度内,可能会存在d' < d
对于每个点做半径为d的圆,落在园内即为d‘比较即可
9.凸包问题
1蛮力法
2快包(类似于快排)
分为上包和下包,
上包就一直寻找 距离两个端点连成的直线最大距离的点(最大三角形面积)
然后端点和该点构成新的端点直线 继续找上包