Table of Contents
因为觉得比较方便,之后的笔记都直接在书上做了,但是没有自己整理浓缩又总害怕不成体系,所以尽量放一些不太理解、记不住的
栈
卡特兰数
常见的问题:n个不同元素进栈,一共有多少种合法的出栈顺序?
合法出栈数目==卡特兰数
凡是合法序列都遵循以下规律:即对于出栈序列中的每一个数字,在它后面的、比它小的所有数字,一定是按递减顺序排列的。
例如:有数字1 2 3 4 依次入栈,那么他们的出栈顺序中:
4321合法:4后面比它小的数是321,并且321递减;3后面比它小的是21,并且21递减。
3421合法:3后面比它小的是21,并且21递减;4后面比它小的是21,并且21递减。
1423不合法:4后面比它小的是23,23不是递减。
例题:
队列
队列的头尾指针常见位置与栈不同:
栈顶指针一般放在栈顶元素处,入栈时先++,栈空时为-1
队列的头指针在头元素,队尾指针在尾元素下一个,队空皆0,入队出队存取完毕再+-指针
循环队列
循环通过取模实现
画成环形时,我在入队出队时指针的移动方向会有迷惑。我的解决办法是,把它掰直确定。
队空队满的判定为循环队列的特殊部分,一般多给一个队头结点,也可用tag。
双端队列
在输入输出连续时:栈的输出输入为逆序,队列的输入输出序列一致
在非连续时:栈会发生变化,队列的输入输出序列仍一致
栈的合法输出序列:出栈序列中,每个元素后面所有比它小的元素组成递减序列
理解:出栈序列中,a<b<c且ab在c后,说明b入栈时,ab未被弹出。这时,a已经没有机会在b之前弹出了
合法出栈序列个数:
根据最后一个出栈元素分类
K最后出栈,比k小的都在k压入前先出栈,比k大的都在k弹出前出栈
可根据k分成两部分计算合法序列:f(k-1)(n-k)
根据k不同,所有分类求和
也可化简为卡特兰数: f(n)=C(2n,n)/(n-1)
双端队列:左右两端都可插入删除
输出受限的双端队列
屏蔽一端得到栈:栈合法的输出序列都可,剩下的一一判断
输出受限-出序定,看入序,大数在外侧两侧
输入受限的双端队列
入序定,看出序
特殊矩阵的压缩存储
以下公式默认是矩阵下标从1开始,压缩数组下标从0开始
对称矩阵
A=AT,aij=aji
存放下三角的元素,所需空间B[n(n+1)/2]:
第一行一个第二行2个…
1+2+…+n,利用等差数列求和公式。
aij在压缩数组中的下标:
上面的所有行:1+2+…+(n-1)
同行的前面:j-1个
第aij个:+1
数组下标从0开始:-1
若求的是上三角区域的元素,只需要把行号列号交换
三角矩阵
存放数组B[n(n+1)/2+1]:同一常量c存放在最后
下三角矩阵
下三角部分与对称矩阵同,上三角的常量通通对应最后一个单元
上三角矩阵
也用等差数列求和
三对角矩阵
i行上面,第一行只存放两个元素,需要-1:3*(i-1)-1
第i行: j-i+1
求原矩阵坐标:
求行号,取下界,数组下标从0开始,每行3个,第一行差一个+1
j通过数组下标公式反解
稀疏矩阵
用三元组保存值与行列
压缩后失去了随机存取特性
习题
栈和队列应用:栈实现递归
将序号压入栈中
计算得值后,出口元素层层解开