算法设计与分析(李春保)练习题答案v2
----------------------------------------------------- Page 1 -----------------------------------------------------
1.1 第 1 章 ─ 概 论
1.1.1 练 习 题
1. 下 列 关 于 算 法 的 说 法 中 正 确 的 有 ( ) 。
Ⅰ . 求 解 某 一 类 问 题 的 算 法 是 唯 一 的
Ⅱ . 算 法 必 须 在 有 限 步 操 作 之 后 停 止
Ⅲ . 算 法 的 每 一 步 操 作 必 须 是 明 确 的 , 不 能 有 歧 义 或 含 义 模 糊
Ⅳ . 算 法 执 行 后 一 定 产 生 确 定 的 结 果
A. 1 个 B.2 个 C.3 个 D.4 个
2. T ( n ) 表 示 当 输 入 规 模 为 n 时 的 算 法 效 率 , 以 下 算 法 效 率 最 优 的 是 ( ) 。
A. T ( n )= T ( n - 1)+1 , T (1)=1 C. T ( n )= T ( n /2)+1 , T (1)=1
B. T ( n )= 2 n
D. T ( n )=3 n log 2 n
3. 什 么 是 算 法 ? 算 法 有 哪 些 特 征 ?
4. 判 断 一 个 大 于 2 的 正 整 数 n 是 否 为 素 数 的 方 法 有 多 种 , 给 出 两 种 算 法 , 说 明 其 中 一 种 算 法 更 好 的 理 由 。
5. 证 明 以 下 关 系 成 立 :
( 1 ) 10 n - 2 n = ( n )
( 2 ) 2 = (2 )
6. 证 明 O( f ( n ))+O( g ( n ))=O(max{ f ( n ) , g ( n )}) 。
7. 有 一 个 含 n ( n >2 ) 个 整 数 的 数 组 a , 判 断 其 中 是 否 存 在 出 现 次 数 超 过 所 有 元 素 一 半 的 元 素 。
8. 一 个 字 符 串 采 用 string 对 象 存 储 , 设 计 一 个 算 法 判 断 该 字 符 串 是 否 为 回 文 。
9. 有 一 个 整 数 序 列 , 设 计 一 个 算 法 判 断 其 中 是 否 存 在 两 个 元 素 和 恰 好 等 于 给 定 的 整 数 k 。
10. 有 两 个 整 数 序 列 , 每 个 整 数 序 列 中 所 有 元 素 均 不 相 同 。 设 计 一 个 算 法 求 它 们 的 公 共 元 素 , 要 求 不 使 用 STL 的 集 合 算 法 。
11. 正 整 数 n ( n >1 ) 可 以 写 成 质 数 的 乘 积 形 式 , 称 为 整 数 的 质 因 数 分 解 。 例 如 , 12=2*2*3 , 18=2*3*3 , 11=11 。 设 计 一 个 算 法 求 n 这 样 分 解 后 各 个 质 因 数 出 现 的 次 数 , 采 用 vector 向 量 存 放 结 果 。
12. 有 一 个 整 数 序 列 , 所 有 元 素 均 不 相 同 , 设 计 一 个 算 法 求 相 差 最 小 的 元 素 对 的 个 数 。 如 序 列 4 、 1 、 2 、 3 的 相 差 最 小 的 元 素 对 的 个 数 是 3 , 其 元 素 对 是 ( 1 , 2 ) , ( 2 , 3 ) , ( 3 , 4 ) 。
13. 有 一 个 map<string , int> 容 器 , 其 中 已 经 存 放 了 较 多 元 素 。 设 计 一 个 算 法 求 出 其 中 重 复 的 value 并 且 返 回 重 复 value 的 个 数 。
14. 重 新 做 第 10 题 , 采 用 map 容 器 存 放 最 终 结 果 。
15. 假 设 有 一 个 含 n ( n >1 ) 个 元 素 的 stack<int> 栈 容 器 st , 设 计 一 个 算 法 出 栈 从 栈 顶 到 栈 底 的 第 k ( 1 ≤ k ≤ n ) 个 元 素 , 其 他 栈 元 素 不 变 。
2
2
2
n +1 n
----------------------------------------------------- Page 2 -----------------------------------------------------
算 法 设 计
1.1.2 练 习 题 参 考 答 案
1. 答 : 由 于 算 法 具 有 有 穷 性 、 确 定 性 和 输 出 性 , 因 而 Ⅱ 、 Ⅲ 、 Ⅳ 正 确 , 而 解 决 某 一 类 问 题 的 算 法 不 一 定 是 唯 一 的 。 答 案 为 C 。
2. 答 : 选 项 A 的 时 间 复 杂 度 为 O( n ) 。 选 项 B 的 时 间 复 杂 度 为 O( n ) 。 选 项 C 的 时 间 复 杂 度 为 O(log 2 n ) 。 选 项 D 的 时 间 复 杂 度 为 O( n log 2 n ) 。 答 案 为 C 。
3. 答 : 算 法 是 求 解 问 题 的 一 系 列 计 算 步 骤 。 算 法 具 有 有 限 性 、 确 定 性 、 可 行 性 、 输 入 性 和 输 出 性 5 个 重 要 特 征 。
4. 答 : 两 种 算 法 如 下 :
#include <stdio.h>
#include <math.h>
bool isPrime1(int n) // 方 法 1
{ for (int i=2;i<n;i++)
if (n%i==0)
return false;
return true;
}
bool isPrime2(int n) // 方 法 2
{ for (int i=2;i<=(int)sqrt(n);i++)
if (n%i==0)
return false;
return true;
}
void main()
{ int n=5;
printf("%d,%d\n",isPrime1(n),isPrime2(n));
}
方 法 1 的 时 间 复 杂 度 为 O( n ) , 方 法 2 的 时 间 复 杂 度 为 n , 所 以 方 法 2 更 好 。 5. 答 : ( 1 ) 当 n 足 够 大 时 , (10 n - 2 n )/( n )=10 , 所 以 10 n - 2 n = ( n ) 。
( 2 ) 2 =2*2 = (2 ) 。
6. 证 明 : 对 于 任 意 f 1 (n) ∈ O( f ( n )) , 存 在 正 常 数 c 1 和 正 常 数 n 1 , 使 得 对 所 有 n ≥ n 1 , 有 f 1 ( n ) ≤ c 1 f ( n ) 。
类 似 地 , 对 于 任 意 g 1 ( n ) ∈ O( g ( n )) , 存 在 正 常 数 c 2 和 自 然 数 n 2 , 使 得 对 所 有 n ≥ n 2 , 有 g 1 ( n ) ≤ c 2 g ( n ) 。
令 c 3 =max{ c 1 , c 2 } , n 3 =max{ n 1 , n 2 } , h ( n )= max{ f ( n ) , g ( n )} 。
则 对 所 有 的 n ≥ n 3 , 有 :
f 1 ( n ) + g 1 ( n ) ≤ c 1 f ( n ) + c 2 g ( n ) ≤ c 3 f ( n )+ c 3 g ( n )= c 3 ( f ( n )+ g ( n ))
≤ c 3 2max{ f ( n ) , g ( n )}=2 c 3 h ( n )=O(max{ f ( n ) , g ( n )}) 。
7. 解 : 先 将 a 中 元 素 递 增 排 序 , 再 求 出 现 次 数 最 多 的 次 数 maxnum , 最 后 判 断 是 否 满 足 条 件 。 对 应 的 程 序 如 下 :
#include <stdio.h>
#include <algorithm>
using namespace std;
2
2
2
2
2
2
n +1 n n
----------------------------------------------------- Page 3 -----------------------------------------------------
第 1 章
概 论
bool solve(int a[],int n,int &x)
{ sort(a,a+n);
int maxnum=0;
int num=1;
int e=a[0];
for (int i=1;i<n;i++)
{ if (a[i]==e)
{ num++;
// 递 增 排 序
// 出 现 次 数 最 多 的 次 数
if (num>maxnum)
{ maxnum=num;
x=e;
}
}
else
{ e=a[i];
num=1;
}
}
if (maxnum>n/2)
return true;
else
return false;
}
void main()
{ int a[]={2,2,2,4,5,6,2};
int n=sizeof(a)/sizeof(a[0]);
int x;
if (solve(a,n,x))
printf(" 出 现 次 数 超 过 所 有 元 素 一 半 的 元 素 为 % d\n",x); else
printf(" 不 存 在 出 现 次 数 超 过 所 有 元 素 一 半 的 元 素 \ n");
}
上 述 程 序 的 执 行 结 果 如 图 1.1 所 示 。
图 1.1
程 序 执 行 结 果
8. 解 : 采 用 前 后 字 符 判 断 方 法 , 对 应 的 程 序 如 下 : #include <iostream>
#include <string>
using namespace std;
bool solve(string str) // 判 断 字 符 串 str 是 否 为 回 文 { int i=0,j=str.length()-1;
while (i<j)
{ if (str[i]!=str[j])
return false;
3
----------------------------------------------------- Page 4 -----------------------------------------------------
算 法 设 计
i++; j--;
}
return true;
}
void main()
{ cout << " 求 解 结 果 " << endl;
string str="abcd";
cout << " " << str << (solve(str)?" 是 回 文 " :" 不 是 回 文 " ) << endl; string str1="abba";
cout << " " << str1 << (solve(str1)?" 是 回 文 " :" 不 是 回 文 " ) << endl; }
上 述 程 序 的 执 行 结 果 如 图 1.2 所 示 。
图 1.2
程 序 执 行 结 果
9. 解 : 先 将 a 中 元 素 递 增 排 序 , 然 后 从 两 端 开 始 进 行 判 断 。 对 应 的 程 序 如 下 : #include <stdio.h>
#include <algorithm>
using namespace std;
bool solve(int a[],int n,int k)
{ sort(a,a+n);
int i=0, j=n-1;
while (i<j)
{ if (a[i]+a[j]==k)
return true;
// 递 增 排 序
// 区 间 中 存 在 两 个 或 者 以 上 元 素
else if (a[i]+a[j]<k)
i++;
else
j--;
}
return false;
}
void main()
{ int a[]={1,2,4,5,3};
int n=sizeof(a)/sizeof(a[0]);
printf(" 求 解 结 果 \ n");
int k=9,i,j;
if (solve(a,n,k,i,j))
printf(" 存 在 : %d+%d=%d\n",a[i],a[j],k); else
printf(" 不 存 在 两 个 元 素 和 为 % d\n",k);
int k1=10;
if (solve(a,n,k1,i,j))
printf(" 存 在 : %d+%d=%d\n",a[i],a[j],k1);
4
----------------------------------------------------- Page 5 -----------------------------------------------------
第 1 章
概 论
else
printf("
不 存 在 两 个 元 素 和 为 % d\n",k1);
}
上 述 程 序 的 执 行 结 果 如 图 1.3 所 示 。
图 1.3
程 序 执 行 结 果
10. 解 : 采 用 集 合 set<int> 存 储 整 数 序 列 , 集 合 中 元 素 默 认 是 递 增 排 序 的 , 再 采 用 二 路 归 并 算 法 求 它 们 的 交 集 。 对 应 的 程 序 如 下 :
#include <stdio.h>
#include <set>
using namespace std;
void solve(set<int> s1,set<int> s2,set<int> &s3) { set<int>::iterator it1,it2;
it1=s1.begin(); it2=s2.begin();
while (it1!=s1.end() && it2!=s2.end())
{ if (*it1==*it2)
{ s3.insert(*it1);
++it1; ++it2;
}
else if (*it1<*it2)
++it1;
else
++it2;
}
}
// 求 交 集 s3
void dispset(set<int> s)
{ set<int>::iterator it;
// 输 出 集 合 的 元 素
for (it=s.begin();it!=s.end();++it)
printf("%d ",*it);
printf("\n");
}
void main()
{ int a[]={3,2,4,8};
int n=sizeof(a)/sizeof(a[0]);
set<int> s1(a,a+n);
int b[]={1,2,4,5,3};
int m=sizeof(b)/sizeof(b[0]);
set<int> s2(b,b+m);
set<int> s3;
solve(s1,s2,s3);
printf(" 求 解 结 果 \ n");
printf(" s1: "); dispset(s1);
5
----------------------------------------------------- Page 6 -----------------------------------------------------
算 法 设 计
printf("
printf("
s2: "); dispset(s2);
s3: "); dispset(s3);
}
上 述 程 序 的 执 行 结 果 如 图 1.4 所 示 。
图 1.4
程 序 执 行 结 果
11. 解 : 对 于 正 整 数 n , 从 i =2 开 始 查 找 其 质 因 数 , ic 记 录 质 因 数 i 出 现 的 次 数 , 当 找 到 这 样 质 因 数 后 , 将 ( i , ic ) 作 为 一 个 元 素 插 入 到 vector 容 器 v 中 。 最 后 输 出 v 。 对 应 的 算 法 如 下 :
#include <stdio.h>
#include <vector>
using namespace std;
struct NodeType
{ int p;
int pc;
//vector 向 量 元 素 类 型 // 质 因 数
// 质 因 数 出 现 次 数
};
void solve(int n,vector<NodeType> &v) // 求 n 的 质 因 数 分 解 { int i=2;
int ic=0;
NodeType e;
do
{ if (n%i==0)
{ ic++;
n=n/i;
}
else
{ if (ic>0)
{ e.p=i;
e.pc=ic;
v.push_back(e);
}
ic=0;
i++;
}
} while (n>1 || ic!=0);
}
void disp(vector<NodeType> &v) // 输 出 v
{ vector<NodeType>::iterator it;
for (it=v.begin();it!=v.end();++it)
printf(" 质 因 数 % d 出 现 % d 次 \ n",it->p,it->pc);
}
6
----------------------------------------------------- Page 7 -----------------------------------------------------
第 1 章
概 论
void main()
{ vector<NodeType> v;
int n=100;
printf("n=%d\n",n);
solve(n,v);
disp(v);
}
上 述 程 序 的 执 行 结 果 如 图 1.5 所 示 。
图 1.5
程 序 执 行 结 果
12. 解 : 先 递 增 排 序 , 再 求 相 邻 元 素 差 , 比 较 求 最 小 元 素 差 , 累 计 最 小 元 素 差 的 个 数 。 对 应 的 程 序 如 下 :
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int solve(vector<int> &myv)
// 求 myv 中 相 差 最 小 的 元 素 对 的 个 数
{ sort(myv.begin(),myv.end()); // 递 增 排 序
int ans=1;
int mindif=myv[1]-myv[0];
for (int i=2;i<myv.size();i++)
{ if (myv[i]-myv[i-1]<mindif)
{ ans=1;
mindif=myv[i]-myv[i-1];
}
else if (myv[i]-myv[i-1]==mindif)
ans++;
}
return ans;
}
void main()
{ int a[]={4,1,2,3};
int n=sizeof(a)/sizeof(a[0]);
vector<int> myv(a,a+n);
cout << " 相 差 最 小 的 元 素 对 的 个 数 : " << solve(myv) << endl; }
上 述 程 序 的 执 行 结 果 如 图 1.6 所 示 。
7
----------------------------------------------------- Page 8 -----------------------------------------------------
图 1.6
算 法 设 计
程 序 执 行 结 果
13. 解 : 对 于 map<string , int> 容 器 mymap , 设 计 另 外 一 个 map<int , int> 容 器 tmap , 将 前 者 的 value 作 为 后 者 的 关 键 字 。 遍 历 mymap , 累 计 tmap 中 相 同 关 键 字 的 次 数 。 一 个 参 考 程 序 及 其 输 出 结 果 如 下 :
#include <iostream>
#include <map>
#include <string>
using namespace std;
void main()
{ map<string,int> mymap;
mymap.insert(pair<string,int>("Mary",80));
mymap.insert(pair<string,int>("Smith",82));
mymap.insert(pair<string,int>("John",80));
mymap.insert(pair<string,int>("Lippman",95));
mymap.insert(pair<string,int>("Detial",82));
map<string,int>::iterator it;
map<int,int> tmap;
for (it=mymap.begin();it!=mymap.end();it++)
tmap[(*it).second]++;
map<int , int>::iterator it1;
cout << " 求 解 结 果 " << endl;
for (it1=tmap.begin();it1!=tmap.end();it1++)
cout << " " << (*it1).first << ": " << (*it1).second << " 次 \ n";
}
上 述 程 序 的 执 行 结 果 如 图 1.7 所 示 。
图 1.7
程 序 执 行 结 果
14. 解 : 采 用 map<int , int> 容 器 mymap 存 放 求 解 结 果 , 第 一 个 分 量 存 放 质 因 数 , 第 二 个 分 量 存 放 质 因 数 出 现 次 数 。 对 应 的 程 序 如 下 :
#include <stdio.h>
#include <map>
using namespace std;
void solve(int n,map<int,int> &mymap) // 求 n 的 质 因 数 分 解
{ int i=2;
int ic=0;
do
{
if (n%i==0)
{ ic++;
n=n/i;
}
8
----------------------------------------------------- Page 9 -----------------------------------------------------
第 1 章
概 论
else
{ if (ic>0)
mymap[i]=ic;
ic=0;
i++;
}
} while (n>1 || ic!=0);
}
void disp(map<int,int> &mymap) // 输 出 mymap
{ map<int,int>::iterator it;
for (it=mymap.begin();it!=mymap.end();++it)
printf(" 质 因 数 % d 出 现 % d 次 \ n",it->first,it->second);
}
void main()
{ map<int,int> mymap;
int n=12345;
printf("n=%d\n",n);
solve(n,mymap);
disp(mymap);
}
上 述 程 序 的 执 行 结 果 如 图 1.8 所 示 。
图 1.8
程 序 执 行 结 果
15. 解 : 栈 容 器 不 能 顺 序 遍 历 , 为 此 创 建 一 个 临 时 tmpst 栈 , 将 st 的 k 个 元 素 出 栈 并 进 栈 到 tmpst 中 , 再 出 栈 tmpst 一 次 得 到 第 k 个 元 素 , 最 后 将 栈 tmpst 的 所 有 元 素 出 栈 并 进 栈 到 st 中 。 对 应 的 程 序 如 下 :
#include <stdio.h>
#include <stack>
using namespace std;
int solve(stack<int> &st,int k)
{ stack<int> tmpst;
int e;
for (int i=0;i<k;i++)
{ e=st.top();
st.pop();
tmpst.push(e);
}
e=tmpst.top();
tmpst.pop();
while (!tmpst.empty())
{ st.push(tmpst.top());
tmpst.pop();
// 出 栈 第 k 个 元 素
// 出 栈 st 的 k 个 元 素 并 进 tmpst 栈 // 求 第 k 个 元 素
// 将 tmpst 的 所 有 元 素 出 栈 并 进 栈 st 9
----------------------------------------------------- Page 10 -----------------------------------------------------
}
return e;
}
void disp(stack<int> &st)
{ while (!st.empty())
{ printf("%d ",st.top());
st.pop();
}
printf("\n");
}
void main()
{ stack<int> st;
算 法 设 计
// 出 栈 st 的 所 有 元 素
printf(" 进 栈 元 素 1,2,3,4\n"); st.push(1);
st.push(2);
st.push(3);
st.push(4);
int k=3;
int e=solve(st,k);
printf(" 出 栈 第 % d 个 元 素 是 : %d\n",k,e); printf("st 中 元 素 出 栈 顺 序 : "); disp(st);
}
上 述 程 序 的 执 行 结 果 如 图 1.9 所 示 。
图 1.9
程 序 执 行 结 果
1.2 第 2 章 ─ 递 归 算 法 设 计 技 术
1.2.1 练 习 题
1. 什 么 是 直 接 递 归 和 间 接 递 归 ? 消 除 递 归 一 般 要 用 到 什 么 数 据 结 构 ? 2. 分 析 以 下 程 序 的 执 行 结 果 :
#include <stdio.h>
void f(int n,int &m)
{ if (n<1) return;
else
{
}
printf(" 调 用 f (%d,%d) 前 , n=%d,m=%d\n",n-1,m-1,n,m); n--; m--;
f(n-1,m);
printf(" 调 用 f (%d,%d) 后 : n=%d,m=%d\n",n-1,m-1,n,m);
10
----------------------------------------------------- Page 11 -----------------------------------------------------
第 1 章
概 论
}
void main()
{ int n=4,m=4;
f(n,m);
}
3. 采 用 直 接 推 导 方 法 求 解 以 下 递 归 方 程 : T (1)=1
T ( n )= T ( n - 1)+ n 当 n >1
4. 采 用 特 征 方 程 方 法 求 解 以 下 递 归 方 程 : H (0)=0
H (1)=1
H (2)=2
H ( n )= H ( n - 1)+9 H ( n - 2) - 9 H ( n - 3) 当 n >2 5. 采 用 递 归 树 方 法 求 解 以 下 递 归 方 程 : T (1)=1
T ( n )=4 T ( n /2)+ n 当 n >1
6. 采 用 主 方 法 求 解 以 下 题 的 递 归 方 程 。
T ( n )=1
当 n =1
T ( n )=4 T ( n /2)+ n 当 n >1
7. 分 析 求 斐 波 那 契 f(n) 的 时 间 复 杂 度 。
8. 数 列 的 首 项 a 1 =0 , 后 续 奇 数 项 和 偶 数 项 的 计 算 公 式 分 别 为 a 2 n =a 2 n -1 +2 , a 2 n +1 =a 2 n - 1 +a 2 n - 1 , 写 出 计 算 数 列 第 n 项 的 递 归 算 法 。
9. 对 于 一 个 采 用 字 符 数 组 存 放 的 字 符 串 str , 设 计 一 个 递 归 算 法 求 其 字 符 个 数 ( 长 度 ) 。
10. 对 于 一 个 采 用 字 符 数 组 存 放 的 字 符 串 str , 设 计 一 个 递 归 算 法 判 断 str 是 否 为 回 文 。
11. 对 于 不 带 头 结 点 的 单 链 表 L , 设 计 一 个 递 归 算 法 正 序 输 出 所 有 结 点 值 。
12. 对 于 不 带 头 结 点 的 单 链 表 L , 设 计 一 个 递 归 算 法 逆 序 输 出 所 有 结 点 值 。
13. 对 于 不 带 头 结 点 的 非 空 单 链 表 L , 设 计 一 个 递 归 算 法 返 回 最 大 值 结 点 的 地 址 ( 假 设 这 样 的 结 点 唯 一 ) 。
14. 对 于 不 带 头 结 点 的 单 链 表 L , 设 计 一 个 递 归 算 法 返 回 第 一 个 值 为 x 的 结 点 的 地 址 , 没 有 这 样 的 结 点 时 返 回 NULL 。
15. 对 于 不 带 头 结 点 的 单 链 表 L , 设 计 一 个 递 归 算 法 删 除 第 一 个 值 为 x 的 结 点 。
16. 假 设 二 叉 树 采 用 二 叉 链 存 储 结 构 存 放 , 结 点 值 为 int 类 型 , 设 计 一 个 递 归 算 法 求 二 叉 树 bt 中 所 有 叶 子 结 点 值 之 和 。
17. 假 设 二 叉 树 采 用 二 叉 链 存 储 结 构 存 放 , 结 点 值 为 int 类 型 , 设 计 一 个 递 归 算 法 求 二 叉 树 bt 中 所 有 结 点 值 大 于 等 于 k 的 结 点 个 数 。
18. 假 设 二 叉 树 采 用 二 叉 链 存 储 结 构 存 放 , 所 有 结 点 值 均 不 相 同 , 设 计 一 个 递 归 算 法 求 值 为 x 的 结 点 的 层 次 ( 根 结 点 的 层 次 为 1 ) , 没 有 找 到 这 样 的 结 点 时 返 回 0 。
11
2
----------------------------------------------------- Page 12 -----------------------------------------------------
算 法 设 计
1.2.2 练 习 题 参 考 答 案
1. 答 : 一 个 f 函 数 定 义 中 直 接 调 用 f 函 数 自 己 , 称 为 直 接 递 归 。 一 个 f 函 数 定 义 中 调 用 g 函 数 , 而 g 函 数 的 定 义 中 调 用 f 函 数 , 称 为 间 接 递 归 。 消 除 递 归 一 般 要 用 栈 实 现 。
2. 答 : 递 归 函 数 f ( n , m ) 中 , n 是 非 引 用 参 数 , m 是 引 用 参 数 , 所 以 递 归 函 数 的 状 态 为 ( n ) 。 程 序 执 行 结 果 如 下 :
调 用 f (3,3) 前 , n=4,m=4
调 用 f (1,2) 前 , n=2,m=3
调 用 f (0,1) 后 , n=1,m=2
调 用 f (2,1) 后 , n=3,m=2
3. 解 : 求 T ( n ) 的 过 程 如 下 :
T ( n )= T ( n - 1)+ n =[T( n - 2)+ n - 1)]+ n =T( n - 2)+ n +( n - 1)
=T( n - 3)+ n +( n - 1)+( n - 2)
= …
=T(1)+ n +( n - 1)+ … +2
= n +( n - 1)+ + … +2+1= n ( n +1)/2=O( n ) 。
4. 解 : 整 数 一 个 常 系 数 的 线 性 齐 次 递 推 式 , 用 x
n -3 3 2 3 2
代 替 H ( n ) , 有 : x = x +9 x - 9 x ,
x - x - 9 x+ 9= x ( x - 9) - ( x - 9)=( x - 1)( x - 9)=( x - 1)( x +3)( x - 3)=0 。 得 到 r 1 =1 , r 2 = - 3 , r 3 =3 则 递 归 方 程 的 通 解 为 : H ( n )= c 1 + c 2 ( - 3) + c 3 3
代 入 H (0)=0 , 有 c 1 + c 2 + c 3 =0
代 入 H (1)=1 , 有 c 1 - 3 c 2 +3 c 3 =1
代 入 H (2)=2 , 有 c 1 +9 c 2 +9 c 3 =2
求 出 : c 1 = - 1/4 , c 2 = - 1/12 , c 3 =1/3 , H ( n )= c 1 + c 2 ( - 3) + c 3 3 = (
n ‒ 1
4
+ 1 3
1
‒ 。
5. 解 : 构 造 的 递 归 树 如 图 1.10 所 示 , 第 1 层 的 问 题 规 模 为 n , 第 2 的 层 的 子 问 题 的 问 题 规 模 为 n /2 , 依 此 类 推 , 当 展 开 到 第 k +1 层 , 其 规 模 为 n /2 =1 , 所 以 递 归 树 的 高 度 为 log 2 n +1 。
第 1 层 有 1 个 结 点 , 其 时 间 为 n , 第 2 层 有 4 个 结 点 , 其 时 间 为 4 ( n /2)=2 n , 依 次 类 推 , 第 k 层 有 4 个 结 点 , 每 个 子 问 题 规 模 为 n /2 , 其 时 间 为 4 ( n /2 )=2 n 。 叶 子 结 点 的 个 数 为 n 个 , 其 时 间 为 n 。 将 递 归 树 每 一 层 的 时 间 加 起 来 , 可 得 :
log n
T ( n )= n +2 n + … + 2 n + … + n ≈
算法设计与分析(李春保)练习题答案v2的更多相关文章
- 算法设计与分析(李春保)练习题答案v1
1.1第1 章─概论 1.1.1练习题 1.下列关于算法的说法中正确的有(). Ⅰ.求解某一类问题的算法是唯一的 Ⅱ.算法必须在有限步操作之后停止 Ⅲ.算法的每一步操作必须是明确的,不能有歧义或含义模 ...
- 算法设计与分析 - AC 题目 - 第 5 弹(重复第 2 弹)
PTA-算法设计与分析-AC原题 - 最大子列和问题 (20分) 给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+, ..., Nj },其中 ≤i ...
- 算法设计与分析 - AC 题目 - 第 2 弹
PTA-算法设计与分析-AC原题7-1 最大子列和问题 (20分)给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+1, ..., Nj },其中 1 ...
- 【技术文档】《算法设计与分析导论》R.C.T.Lee等·第7章 动态规划
由于种种原因(看这一章间隔的时间太长,弄不清动态规划.分治.递归是什么关系),导致这章内容看了三遍才基本看懂动态规划是什么.动态规划适合解决可分阶段的组合优化问题,但它又不同于贪心算法,动态规划所解决 ...
- 算法设计与分析-Week12
题目描述 You are given coins of different denominations and a total amount of money amount. Write a func ...
- 算法设计与分析 - 李春葆 - 第二版 - pdf->word v3
1.1 第1章─概论 练习题 . 下列关于算法的说法中正确的有( ). Ⅰ.求解某一类问题的算法是唯一的 Ⅱ.算法必须在有限步操作之后停止 Ⅲ.算法的每一步操作必须是明确的,不能有歧义或含义模糊 Ⅳ. ...
- 算法设计与分析 - 李春葆 - 第二版 - html v2
1 .1 第 1 章─概论 1.1.1 练习题 1 . 下列关于算法的说法中正确的有( ). Ⅰ Ⅱ Ⅲ Ⅳ .求解某一类问题的算法是唯一的 .算法必须在有限步操作之后停止 .算法 ...
- 算法设计与分析 - 李春葆 - 第二版 - pdf->word v1
章─概论 练习题 . 下列关于算法的说法中正确的有( ).Ⅰ.求解某一类问题的算法是唯一的 Ⅱ.算法必须在有限步操作之后停止 Ⅲ.算法的每一步操作必须是明确的,不能有歧义或含义模糊Ⅳ.算法执行后一定产 ...
- 南大算法设计与分析课程复习笔记(1) L1 - Model of computation
一.计算模型 1.1 定义: 我们在思考和处理算法的时候是机器无关.实现语言无关的.所有的算法运行在一种“抽象的机器”之上,这就是计算模型. 1.2 种类 图灵机是最有名的计算模型,本课使用更简单更合 ...
随机推荐
- 【设计模式】Adapter
前言 Adapter设计模式,允许客户端使用接口不兼容的类. 昨天收拾一些以前的东西,发现了藏在柜子里的一条线,这条线叫做OTG.这条线的一端是micro-usb的输出口,另一端是usb的输入口.这条 ...
- python中pip添加国内镜像源后显著加速下载
python中pip添加国内镜像源后显著加速下载 更换pip源到国内镜像,很多国外的库下载非常慢,添加国内镜像后安装下载速度提升非常明显(亲测有些可以由几十kb加速到几MB) pip国内的一些镜像阿里 ...
- 手写instanceof (详解原型链) 和 实现绑定解绑和派发的事件类
A instanceof B 是判断 A 是否继承自B,是返回true, 否返回false 再精确点就是判断B 是否 再 A 的 原型链上, 什么是原型链,举个例子: 我们定 ...
- 关于css中布局遇到的一些问题
现在本人初学网页布局经常遇到一些布局问题比如图片错位. 遇到的问题以及解决方案如下 行内元素有缝隙 块级元素没有缝隙 行内块元素中间会有小缝隙 常见的解决办法就是浮动
- Arduino leonardo+esp8266-01作服务端与APP进行数据通信
esp8266-01调试 一.硬件设备 1.USB转TTL 2.esp8266-01 3.杜邦线 4.电脑 二.接线 ESP8266 TTL-USB VCC VCC(最好选择3.3V) CH_PD V ...
- 获取mac地址和扫描端口
获取IP mac地址 arp -a 10.0.0.34 扫描指定IP 1到30000端口 nmap -p1-30000 10.0.0.36
- [PHP] 使用ftell和fseek函数直接定位文件位置获取部分数据
对于大文件只获取部分数据很有用 1.使用ftell函数可以获取当前指针的字节位置2.使用fseek函数可以直接定位到指定的位置3.读取指定字节的数据就可以部分获取文件内容了 <?php clas ...
- 全球唯一标识符 System.Guid.NewGuid().ToString()
System.Guid.NewGuid().ToString(); //ToString() 为 null 或空字符串 (""),则使用"D". 结果:8209 ...
- kerberos&LDAP实现免密码登录搭建
kerberos && openldap 1.install openldap & kerberos server: yum install db4 db4-utils db4 ...
- slf4j 和 logback 的区别
slf4j 和 logback 的区别: slf4j是Java的一个日志门面,实现了日志框架一些通用的api; logback是具体的日志框架.它和log4j是同一个作者,他是为了解决log4j存在的 ...