DSA 问题集第四章
数据结构问题集第四章。

b) 使用一个累加器 acc,每次进入下一层逻辑前利用当前层逻辑更新 acc

把 (+,+) 改成 <,空间对于连加情况由 O (1) 到 O (n),时间不变。

1 | 0001 const char pri[9][9] = { //优先级快查表[栈顶][当前] |
因为右括号永远不进栈。栈底 0 和右括号,栈中左括号和 0 不可能见面否则括号失配;!和 (也不会相邻。

d) 用一个极小的数值 10-9 和浮点数比较

a) 都是从低优先级到高优先级,否则会触发计算过程
b)1+2*(1+2)
c) 不是。((((((1))))))
d)1+2*3^(1+2*+3^(…)),n/4

a) k 先出栈意味着 ij 已经先入栈了,于是 ij 相对顺序是 (j…i)
b) 同理

[0,n),如果是 stack [i] 最后进入 B 栈前面 (0,i) 自己玩自己的,而后 [i] 入中转栈然后直到最后才出去,(i,n) 自己玩自己的,$SP (n)=\sum^{n-1}_1 {SP (i)*SP (n-i-1)}$
a) b) 一样的

a)Sa 需要一直在中转栈底部,而 C 紧邻 Sa 在前面,所以 C 必须先出中转栈
b)C4=14
c)Sb 出栈时全栈空,所以在它前面的都出栈了。由于 Sb 必须等最后出栈,所以 A 先出在 Sb 紧邻前面
d)14
e) 都是 C3=5
f) 中间是 TDSb 和 SaTD 的混洗。TDS,TSD,DTS,SDT 相同 4 个,不同 1 个
g) 容斥原理:14 + 14-4 = 24 个

1 | 0001 Rank spCheck( Vector<Rank>& B ) { //B = unsort[1,n] |
如果序列合规,算法进行到第 r 步需要考查栈顶和序列当前位置。如果当前和栈顶相同就 pop 模拟中转栈出栈;如果不同说明当前需要的元素还在 A 栈里,需要不断的压栈直到栈顶和当前位置相同,出栈。
如果不合规,则有两种情况。如果 B [r]<A 说明 B [r] 比当前入栈的 A 还要小,但是入栈序列是递增的,那么说明 A 一定在之前入栈过了;n < A 说明 n 个元素都入中转栈但是还是没有栈顶。
如果合法,每个元素都需要经历入一次出一次栈,总体 O (n)。而最坏情况下 while 循环需要遍历整个序列直到在底部找到当前需要的元素, O (n)。


一次 push 等同于写下一个左括号,一次 pop 等同于写下一个右括号。
由于不能对空栈出栈,所以任何时刻入栈次数 >= 出栈次数,任何时刻左括号 >= 右括号,最后两种操作相等保证括号数相等。

1 | 0001 uint64_t mr_STACK( uint64_t H[], Rank n ) { //单趟扫描版 |
a) 每个元素发 2 块钱,出栈用一块入栈用一块,总共 2n 块钱,O (n)
b) 统计整个生命周期的行为。每个元素必然且仅一次出入栈,所以总共 2n,O (n)
c) 定义势能函数 $\Phi (D_i)=|stack|,A_i = T_i+\Delta \Phi (D_i)$
入栈 1 个,出栈 ki 个,Ti=1+ki,势能变化 ki-1
$\sum{A_i}=2n=\sum{T_i},O(n)$

a) b) 最好 O (1),最坏 O (n)
c) 开的最大栈空间就是 maxSr
d) 在 r 处,栈中存储 [1,r],[2,r]…[r-1,r],[r,r] 一共 r 个后缀中的所有最小值。考查第 k 个元素,想要成为后缀最小值必须是 [k,r] 的最小值,概率是 1/(r-k+1)。累加是调和级数求和一共 O (logr)
e) O (logn),具体为什么不清楚。



a)
d:Q 出队,Y 取头,Y 出队。3
e:Q 入队,Y 入队,Y 判空必然会有 e 次,Y 找队尾必然会有 e 次。4
c:Y 判空,Y 队尾,Y 反向出队。3

b) 每个元素分配 4 块钱,Q 入队出队一共消耗两个,Y 入队最多消耗一个(因为当前元素不一定入队),无论正向还是反向,出队消耗一个。一共不超过 4n,于是 O (n)
c) 定义势能函数 $\Phi (D_i)=|Y|$
出队:$A_i = T_i+\Delta\Phi (D_i),Y 不出队: A_i = 1+0 = 1;Y 出队: A_i = 2+(-1)=1$
入队:$A_i = 2+k_i+(1-k_i)=3$
于是均摊必然是 O (1)
空间:从右往左数,第 k 个元素能够成为后缀最大值并存在于队列中的概率是 1 / k,调和级数求和,期望是 O (logn)