
递归与分治
yuanba_xs
分享程序员的体会与知识
展开
-
快速排序实现以及时间复杂度分析
快速排序思想:1.选择数组左边第一个元素为枢轴pivot,把数组所有元素比pivot大的放在数组右边,比pivot小的放在左边(复杂度为O(n))2.对pivot左右两边的序列分别进行快速排序。平均时间复杂度分析:T(1) = 1;T(n) = 2*T(n/2) + a*n;(a为常数,每次合并时,复杂度为O(n))= 2*(2*T(n/4)+a*n/2) + a*原创 2017-03-13 22:11:57 · 3547 阅读 · 0 评论 -
汉诺塔问题
#include using namespace std;void Hano(int n, char src, char mid, char aim)//把n个盘子从src通过mid移动到aim中 { if(n==1) { cout " << aim << endl; return; } Hano(n-1,src,aim,mid); cout " << aim <<end原创 2017-03-13 22:29:28 · 253 阅读 · 0 评论 -
百练:爬楼梯
树老师爬楼梯,每次可以爬一阶或者两阶,共有n阶楼梯,问有多少走法。爬n阶台阶可以分为:1.先爬一阶台阶,再爬n-1阶台阶。2.先爬两阶台阶,再爬n-2阶台阶。最后得出递归表达式f(n) = f(n-1)+g(n-2);#include #define N 100005using namespace std;int f(int x){ if(x==1||x==2) r原创 2017-03-13 22:28:56 · 365 阅读 · 0 评论 -
百练:算24
描述给出4个小于10个正整数,你可以使用加减乘除4种运算以及括号把这4个数连接起来得到一个表达式。现在的问题是,是否存在一种方式使得得到的表达式的结果等于24。这里加减乘除以及括号的运算结果和运算的优先级跟我们平常的定义一致(这里的除法定义是实数除法)。比如,对于5,5,5,1,我们知道5 * (5 – 1 / 5) = 24,因此可以得到24。又比如,对于1,1,4,2,我们原创 2017-03-13 22:28:30 · 433 阅读 · 0 评论 -
百练:放苹果
把m个相同的苹果放在n个相同的盘子里,允许有的盘子空着不放,问共有多少种不同的放法?5,1,1和1,5,1是同一种放法#include using namespace std;int f(int m, int n){ if(m<n) return f(m,m); if(m==0) return 1; if(n==0) return 0; else return f(m,原创 2017-03-13 22:27:43 · 242 阅读 · 0 评论 -
求主元素
求主元素:先求出中位数,由于主元素必为中位数,因此只需要判断中位数出现次数是否大于n/2即可。寻找中位数:用线性方法寻找第k大的数即可在O(n)内找到中位数。设T[0:n-1]是n个元素的数组。对任一元素x,设S(x)={ i | T[i]=x}。当|S(x)|>n/2时,称x为主元素。设计一个线性时间算法,确定T[0:n-1]是否有一个主元素。#include #inclu原创 2017-03-13 22:25:09 · 493 阅读 · 0 评论 -
线性时间寻找一列无序数中第k大的数
线性时间寻找一列无序数中第k大的数分治思想#include #include #include #include #define N 100005using namespace std;int partition(int a[], int s, int e){ int m = (s + e) / 2; int i = s, j = e; int pivot = a[s原创 2017-03-13 22:24:22 · 578 阅读 · 0 评论 -
求一列数前m大的数
思想:一.先排序,在输出后m个元素。(复杂度O(nlogn))二.先把前m大的元素弄到数组最右边,在对这m个数进行排序(复杂度为O(n+mlogm),其中把前m大的元素弄到数组最右边花费为O(n))如何把前m大的元素弄到数组最右边?1.以a[0]为枢轴,把比他大的放在其后,比它小的放在其前。记录它比他大的元素个数(包括自己)为cnt若cnt==m,函数结束 cnt原创 2017-03-13 22:22:21 · 726 阅读 · 1 评论 -
求逆序对个数(分治)
求逆序对个数在归并排序(从大到小)的合并过程前,对两个分支进行逆序对数的计算(该计算过程为O(n))#include #include #include #define N 100005using namespace std;int a[N], b[N];void Merge(int a[], int s, int m, int e, int tmp[]){ int p原创 2017-03-13 22:21:34 · 2535 阅读 · 0 评论 -
递归:求波兰表达式
波兰表达式的定义:1.一个数是波兰表达式,其结果就是该数的值2.“运算符 波兰表达式 波兰表达式”,也是波兰表达式,其值为两个波兰表达式的值的计算结果#include #include #include #define N 20using namespace std;double exp()//读入一个逆波兰表达式,返回其结果{ char s[N]; cin >> s原创 2017-03-13 22:20:41 · 1419 阅读 · 0 评论 -
百练:简单整数划分
整数划分问题是算法中的一个经典命题之一,有关这个问题的讲述在讲解到递归时基本都将涉及。所谓整数划分,是指把一个正整数n写成如下形式:n = m1 + m2 + ... + mi; (其中mi为正整数,并且1 <= mi <= n),则{ m1,m2,...,mi }为n的一个划分。如果{ m1,m2,...,mi }中的最大值不超过m,即max(m1, m2, ..., mi) <= m,则原创 2017-03-13 22:19:54 · 273 阅读 · 0 评论 -
poj1731输出不重复全排列
已知一个序列,输出它的不重复全排列思路1.stl应用:next_permutation函数对数组输出全排列,原理每次改变当前字符串变为,大小恰好原来大一阶的序列。若已为最大序列,返回0。说明:next_permutation,重新排列范围内的元素[第一,最后一个)返回按照字典序排列的下一个值较大的组合。返回值:如果有一个更高的排列,它重新排列元素,并返回true;如果这是不可能原创 2017-02-08 18:54:19 · 670 阅读 · 0 评论 -
百练:2的幂次方表示
#include #include #include using namespace std;void f(int n){ if (n == 1) { cout << "2(0)"; return; } if (n == 2) { cout << "2"; return; } int num = 1, cnt = 0; while (num <= n)原创 2017-03-13 22:16:26 · 543 阅读 · 0 评论 -
N皇后问题
以下为只输出结果的代码include #include #define N 10using namespace std;int vis[3][2*N];//分别标记列,主对角线,副对角线。注意对角线可能有2*n-1个,数组要开大点。int n;int cnt = 0;void dfs(int cur)//cur表示当前行,i*i方阵{ if (cur > n)//已放满原创 2017-03-13 22:15:38 · 189 阅读 · 0 评论 -
归并排序实现及时间复杂度分析
归并排序思想:1.把序列分为两部分,对两部分分别排序(拆分的边界条件:元素大于1个)2.合并已排序两部分时间复杂度分析:T(1) = 1;T(n) = 2*T(n/2) + a*n;(a为常数,每次合并时,复杂度为O(n)) = 2*(2*T(n/4)+a*n/2) + a*n = 4*T(n/4) + 2*a*n = 4*(2*T(n/8)+a*n原创 2017-03-13 22:13:11 · 777 阅读 · 0 评论 -
主定理
主定理 d n=2T(n) = aT(n/c)+bn^x n>2 θ(n^x) aT(n) = θ(n^x*logn) a=n^x θ(n^logc(a)) a>n^x原创 2017-03-13 22:32:07 · 565 阅读 · 0 评论