算法设计技巧与分析习题参考答案
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
习题4.13
(b)元素最大交换次数:A9~A5 各1次;A4~A3 各2次;A2最多3次;A1最多4次 最多共需16次元素交换
4.13另解:
考虑第i个节点,其子节点为2i,则最多可交换1次;若子节点有子节点22i, 则最多可交换2次;若…..有子节点i×2k, 则最多可交换k次;
因此有
i×2k≤ 19
求出满足上述不等式的最大的k值即可。
i=1时, k=4;
i=2时, k=3;
i=3或4时, k=2;
i=5~9时, k=1;
因此最多交换4+3+2×2+1×5=16次
6.5 用分治法求数组A[1…n]元素和,算法的工作空间是多少?输入:数组A[1…n]
输出:数组的所有元素之和∑A[i] {i=1…n}
SUM(low, high)
1.if high = low then
2.return A[low]
3.else
4.mid←⎣(low+high)/2⎦
5.s1←SUM(low,mid)
6.s2←SUM(mid+1, high)
7.return s1+s2
8.end if
工作空间:mid~Θ(logn), s1&s2~Θ(1)(后序遍历树,不断释放空间,故为常数Θ(1)),总的工作空间为Θ(logn).
6.6 用分治法求元素x在数组A中出现的频次。
freq(A[low, high], x)
1.if high=low then
2.if A[low]=x then
3.return 1
4.else
5.return 0
6.end if
7.else
8.mid ←⎣(low+high)/2⎦
9.f1 ←freq(A[low, mid])
10.f2 ← freq(A[mid+1, high])
11.return f1+f2
12.end if
复杂度:T(n)=T(⎣n/2⎦)+ T(⎡n/2⎤)≈2T(n/2) (设2k≤n<2k+1) =…=2k T(n/2k) =2k T(1) = n
6.16修改后的MERGESORT算法
最大比较次数
(1)/2
()
2(/2)1
n n if n m T n
T n n if n m
-≤
⎧
=⎨
+->
⎩
最小比较次数
1
()
2(/2)/2
n if n m C n
C n n if n m
-≤
⎧
=⎨
+>
⎩
令n/2k=m≥2,展开可知:
T(n)= 2k T(n/2k) + kn - (2k-1)
= n/m×m(m-1)/2 + nlog(n/m)- n/m+1
= n(m-1)/2 + nlog(n/m) -n/m+1
若T(n)=Θ(nlogn), 其中表达式有nm, nlogn, nlogm, n/m等. 有n/m < nlogm < nm且须有nm=O(nlogn), i.e., nm ≤ c·nlogn, 则须有m≤c·logn. 可令c=1,则m≤logn. 另一方面,
C(n) = 2k C(n/2k)+kn/2 = n/m×(m-1) + (n/2)log(n/m)= Θ(nlogn)
6.35
split(A[low,...high])
1. x←A[low] //备份为x
2. while (low 3. while (low 4. A[low] ←A[high] 5. while (low 6.A[high] ←A[low] 7.} 8.A[low] ← x//这时, low=high 7.3 动态规划法计算二项式系数k n C ,并分析其时间复杂度。 1. for i←1 to n 2. C[i,0] ← 1; C[i, i ] ←1 3. end for 4. for i←2 to n 5. for j ←1 to i-1 / min(k, i-1) //例如计算C[6,2] 6. C[i,j] ←C[i-1,j-1] + C[i-1,j] 7. end 8. end for 9. return C[n.k] 复杂度分析: 212(1)(1)2 n n i j i i cn n c i c c i ====-=-===∑∑∑∑i-1n-1 2 1Θ(n ) 或 212(1)n n i j i c kc ck n =====-=∑∑∑k O(nk) 8.5硬币的面值为1, 2, 4, 8, ..., 2k, 要兑换的值n<2k+1,用贪心 算法解这个问题,要求算法复杂度为O(log n) 输入:k+1个不同硬币的面值,其中包括单位币(面值为1)输出:若要兑换的值n,给出各个面值硬币的数目num[0…k] 1.将k+1个不同的面值按递增顺序排列,记为Value[0...k] 2.num[0…k]←0 3.fo r j← k downto 0 4.num[j] ←⎣n/Value[j]⎦ 5.n←n - num[j]×Value[j] 6.end for 7.return num[0…k]