算法分析与设计
文章平均质量分 76
Raise
记录下来的目的主要是为了加深自己的理解,如果还能对一两个人起到抛砖引玉的作用,就再高兴不过了。
展开
-
算法导论第9章(o(3n/2)时间内找出最大最小值)
#include #include //包含INT_MAX,INT_MIN的头文件 int nMax = INT_MIN; //将INT_MIN设为当前最大值的初始值int nMin = INT_MAX;/////记录比较最大值函数void Max(int& nNum){ nMax = nNum > nMax ? nNum : nMax ;}/////记录比较最小值原创 2013-05-18 00:30:33 · 1828 阅读 · 0 评论 -
算法导论 9.1-1 求第二小元素
转自http://blog.csdn.net/mishifangxiangdefeng/article/details/7983809#include #includeusing namespace std;//第一遍求最小值的结果用树表示struct node{ int key; node *next;//指向同一层中的下一个元素 node *p; //父指针 node转载 2013-05-18 21:35:55 · 1551 阅读 · 0 评论 -
算法导论第9章最坏情况为线性时间的选择算法
题目:实现找中位数的中位数。思路:自顶向下的思维方式,首先将一个长数组划分成每5个元素为一小组的几个小的数组,然后对每一个小的数组进行插入排序,返回第3个元素,将其保存在一个新的数组B中,再对B进行找中位数操作,这里并不进行排序,而是利用第9章的Select算法,直接返回第(a+b)/2小的元素(即中位数)即可。步骤:1将长数组划分成小数组。 2将每个小数组进行insert_sor原创 2013-05-19 16:29:24 · 3912 阅读 · 0 评论 -
C++ 中析构函数为什么要求是虚的
这是因为,通过基类指针来销毁派生类对象这个行为,当基类没有虚析构函数时会产生问题。我们知道删除指针对象是没有问题的,指针对象的析构函数会正确调用,但仅限于指针的类型所表示的对象大小。如果以一个基类指针指向其派生类,删除这个基类指针只能删除基类对象部分,而不能删除整个派生类对象,原因是通过基类指针无法访问派生类的析构函数。但是,如果像其它虚函数一样,基类的析构函数也是虚的,那么派生类的析构函数也原创 2013-05-10 23:49:43 · 4754 阅读 · 1 评论 -
快速排序及其中的两种划分中枢点的方法
#include "stdio.h"void q_sort(int a[],int l,int r);void swap(int& a,int& b);int partition1(int a[],int l,int r);int partition2(int a[],int l,int r);int main(){ int a[]={1,5,2,4,1,5,3,6,8,0,5,3,原创 2013-05-11 00:42:41 · 2247 阅读 · 0 评论 -
随机版的快速排序分析方法
随机版的快速排序(Randomized Quicksort)。运行时间不依赖于输入的排序情况最坏情况仅由随机数的生成决定 通常的做法是随机地选择主元(pivot)。T(n)为渐近运行时间,其期望值(Expectation)为E[T(n)],我们希望对所有的输入,找出这个期望值。对k=0,1,2,...,n-1,我们定义一个0-1随机变量X_k:X_原创 2013-05-11 16:18:12 · 1852 阅读 · 0 评论 -
算法导论7.4-5
题目:当输入数据已经“几乎有序时”,插入排序很快,在实际应用中,我们可以利用这一特点来提高快速排序的速度。当对一个长度小于k的子数组调用快速排序时,让它不做任何排序就返回。当上一层的快速排序调用返回后,对整个数组运行插入排序完成排序过程。证明:这一排序算法的期望时间复杂度为O(nk+nlg(n/k)).解决方案:quicksort在递归到只有几个元素大小的数组时开始用插入排序的方法。...原创 2018-12-30 11:25:45 · 5312 阅读 · 2 评论 -
快速排序非递归实现
#include "stack"#include "stdio.h"#include "vector"using namespace std;void swap1(int& a,int& b){ int temp=a; a=b; b=temp;}//强大的异或,不需要用到暂时变量就可以实现二者互换void swap2(int& a,int& b){ if (a!=b)原创 2013-05-12 17:15:12 · 1654 阅读 · 0 评论 -
二叉树的先序遍历非递归实现方法
#include "iostream"using namespace std;struct node { int key; node* left; node* right; node(){} node(int x):key(x),left(NULL),right(NULL){}};struct Tree { node* root; Tree():root(NULL){}}原创 2013-05-10 16:06:08 · 1546 阅读 · 0 评论 -
算法导论7-5(三数取中划分)
算法导论7-5:a.对于i=2,3,4,...........,n-1,请给出以n和i表示的Pi的准确表示式:从n个数中选择3个,一共有种情况,要求i是3个数中的中位数,则当i选定时,剩余的2个数中,必须其中一个在i左边,一个在i右边,i左边有i-1种选择,i右边有n-i种选择,则(i−1)(n−i)C3b.(i−1)(n−i)C3n由a.公式可知道选取中位数的概率等于,平...原创 2018-12-30 11:25:52 · 4845 阅读 · 0 评论 -
算法导论7.6对区间的模糊排序
题目:7-6 对区间的模糊排序 考虑这样的一种排序问题,即无法准确地知道待排序的各个数字到底是多少。对于其中的每个数字,我们只知道它落在实轴上的某个区间。亦即,给定的是n个形如[ai,bi]的闭区间,其中ai≤bi。算法的目标是对这些区间进行模糊排序(fuzzy-sort),亦即,产生的各区间的一个排列,使得存在一个cj∈[ai, bi],满足c1≤c2≤...≤cn。原创 2013-05-13 13:11:11 · 3929 阅读 · 2 评论 -
算法导论 第7章 课后习题
转自http://www.cnblogs.com/bigrabbit/archive/2012/06/08/2541356.html,中间有新增7.2-4 银行经常按照交易时间,来记录有关某一账户的交易情况,但是,很多人喜欢按照票据号来收到其银行对账单。因此,如何将按交易时间排序转换成按支票编号来排序,就成为一个对几乎排好序的输入进行排序的问题。证明在这个问题上,过程INSERT_SORT的性转载 2013-05-13 12:54:13 · 2285 阅读 · 0 评论 -
算法导论第三版7-3证明
1.积分法证明:用mathtype另行敲了一遍,看起来可能会舒服一些。2.拆分法证明:取这个有一点小技巧,这可以保证前边部分元素a比后边部分的元素个数b少,即a<n/2 ,所以lgn-1比lgk要大,因为lgn-1-lgk=lg(n/k)-1>0。 ...原创 2018-12-30 11:25:40 · 2834 阅读 · 0 评论 -
算法导论-13-1-持久动态集合
部分引用博客:http://blog.csdn.net/mishifangxiangdefeng/article/details/7903794部分为个人观点。写在前边:本来知道debug很强大,今天晚上才发现,debug原来可以发现这么多疏漏的地方,用好debug确实可以事半功倍。参考答案:a)需要改变的结点包括“从根结点开始,到要插入到删除的结点原创 2013-06-09 22:26:54 · 2250 阅读 · 1 评论 -
算法导论11.2-4
更详细的见点击打开链接,这里只说一下自己的观点。这里是以槽位为操作对象的,本人认为在头脑中建立一个好的数学模型对于编程有很大帮助。每个槽位定义为一个node{key,flag,pre,next}需要一个自由链表,单链表即可。表头是Free=0;定义两个操作自由链表的函数,这很容易想到,即从自由链表中移出一个结点RemoveFromFree(槽对象),或将一个(node)槽对象加原创 2013-05-25 19:35:32 · 2203 阅读 · 0 评论 -
[面试中的算法]把二元查找树转变成排序的双向链表
题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向比如二叉搜索树:输出应为: 3, 4, 5, 10, 11, 12, 13:分析:处理树状结构很容易想到递归,而二叉搜索树其实恰好是已经排序好的一个结构,而要把它变成链接,只需“中序遍历”即可: 3,4,5,10,11,12,13,中序遍历每访问到一个节点的时候,需要原创 2013-07-15 11:55:48 · 1479 阅读 · 0 评论 -
定义栈的数据结构在Theta(1)时间复杂度内实现min,pop,push操作
思路:push,pop操作在常量时间复杂度内完成,没有问题,但是,min操作需要在常量时间复杂度内完成,一开始很容易想到在栈中保存一个变量min,用来保存最小值,那么如果需要min()操作时,只需要查min变量的值即可.这个思路看起来不错,但是,有一个致命的缺陷,那就只是,只保存一个min变量,那么当min也需要弹栈的时候,那么栈中的min也需要用次二小的值更新,但是,此时无法知道第二个小值是原创 2013-07-29 17:58:47 · 2128 阅读 · 0 评论 -
不用+,-,x,/做加法运算
废话少说,直接上例子。例如要算14+8的和,平常的思维方式,4+8得2进1,1+1得2不进位,结果就是22.思维方式就是自右往左,边加边求和,再进位,再重复以上步骤。但是,现在限制住了加减乘除,剩下的只有与或非了。于是加可用异或,求进位可用与,重复上述步骤直到结果正确即可。改进一下,我们可分为三步走:1,整体求和(异或)2,整体求进位(与)3,重复以上步骤(循环或递归)C++代原创 2013-07-23 12:48:09 · 1516 阅读 · 0 评论 -
数组中找出两个只出现一次的数字
题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。思路:题目要求时间复杂度是O(n),空间复杂度是O(1),这说明基于比较的办法求解无法完成,这题需要异或的性质,异或(同为0,异为1,相当于不进位加法)因为其它数都出现两次,当扫描完一次之后,将所有的数做异或,那些相同的数都会变成0,结果是两个不...原创 2018-12-30 11:26:13 · 3968 阅读 · 0 评论 -
菜园四周种了n棵白菜,并按顺时针方向由1到n 编号,收割时,从编号1开始,按顺时针方向每隔两棵白菜收割一棵,直到全部收割完毕为止.按收割顺序列出白菜编号
这里中的一种算法题目:书中用数组来解决代码:#include using std::cout;void reap(int* Circle,int* result, int n){ int k = 3;//轮子 int s = n;//跟踪A数组的末尾 int j=0;//跟踪result数组末尾 while(j < n)//result数组如果填满,则出局顺序完成 {原创 2013-07-30 15:07:14 · 1600 阅读 · 0 评论 -
[编程题]用递归求数组最大值的位置(索引,下标)
题目:这道题难度并不大,因为是需要用递归的思想来解决,我们很容易就能够想到分治的思想.首先,定义一个函数MaxIndex()并假定它可以返回数组最值的索引(索引相对于数组开始而言,即相对开始偏移了多少.).至少MaxIndex()是如何工作的,暂时不需要管.只需要知道,它可以返回最大值的索引不妨设为p.因此可以将数组分为1和n-1两等份.对后者调用MaxIndex()可得到最大值下标偏移量.即最大...原创 2018-12-30 11:25:24 · 6045 阅读 · 0 评论 -
二叉树非递归:中序,先序,后序,统一格式
终于整理齐了。#include #include using namespace std;struct node//结点{ int key; node* p; node* left; node* right; node(){} node(int k):key(k),p(NULL),left(NULL),right(NULL){}};struct TREE//树{原创 2013-07-14 00:49:58 · 1594 阅读 · 0 评论 -
斐波那契数列时间复杂性的近似证明和精确证明
斐波那契数列可以派生出很多应用,其中,我们知道它的时间复杂性是指数级的,现在就来粗略地证明一下:斐波那契数列递推式:F(n)=F(n-1)+F(n-2)F(1)=F(2)=1粗略证明可以利用Decision_Tree,为了更直观,我引用另一个恒等函数 f(x)=0 ;x=1,2,3,4,5,............所以斐波那契数列递推式变形如下:F(n)=F(n-1)+F(原创 2013-07-27 23:38:28 · 2539 阅读 · 0 评论 -
用两个栈实现一个队列:实现出队列和入队列功能,用两个队列实现一个栈
思路:用两个栈来模仿队列,就是要用两个后进先出的数据结构来实现先进先出的功能。举个简单的例子:(用#代表栈底,->表示队列的方向)初始状态:可以知道,这是可行的,如果需要出队列,只需要stack1不停弹栈即可stack 1: #4,3,2,1stack 2: #queue:4,3,2,1->此时如果需要入队列,那么队列就应该是这样子:queue : 5,4,3,2,1->原创 2013-07-27 20:36:04 · 2733 阅读 · 0 评论 -
查找单链表中倒数第k个结点||旋转单链表
思路:由于是单链表,没有办法先通过遍历到最末尾,然后,回朔k个结点(k从1开始数起)的办法解决。还可以通过一个低效的办法做到,先遍历一次确定链表的总数n,第二次遍历时,遍历到n-k+1位置时即可。但是这样需要扫描链表两次。还有一个高效的办法,就是管理两个指针,前边的指针先行k个结点,然后两个指针同步前移,当前边的指针到达末尾时,后面的指针刚好是倒是k个结点。#includeusi原创 2013-07-28 14:28:49 · 1357 阅读 · 0 评论 -
实现一个栈,使push,pop,min操作只需要o(1)时间
思路: push,pop操作在常量时间复杂度内完成,没有问题,但是,min操作需要在常量时间复杂度内完成,一开始很容易想到在栈中保存一个变量min,用来保存最小值,那么如果需要min()操作时,只需要查min变量的值即可.这个思路看起来不错,但是,有一个致命的缺陷,那就只是,如果只保存一个min变量,那么当min也需要弹栈的时候,那么栈中的min也需要用次二小的值更新,但是,此原创 2013-08-07 10:51:58 · 3822 阅读 · 0 评论 -
微软一道面试题
一个整数数列,元素取值可能是0~65535中的任意一个数,相同数值不会重复出现。0是例外,可以反复出现。 请设计一个算法,当你从该数列中随意选取5个数值,判断这5个数值是否连续相邻。 注意: - 5个数值允许是乱序的。比如: 8 7 5 0 6 - 0可以通配任意数值。比如:8 7 5 0 6 中的0可以通配成9或者4 - 0可以多次出现。原创 2013-08-09 22:21:31 · 1429 阅读 · 0 评论 -
腾讯面试题,给你10分钟时间,根据上排给出十个数,在其下排填出对应的十个数
题目:给你10分钟时间,根据上排给出十个数,在其下排填出对应的十个数要求下排每个数都是先前上排那十个数在下排出现的次数。上排的十个数如下:【0,1,2,3,4,5,6,7,8,9】举一个例子,数值: 【 0,1,2,3,4,5,6,7,8,9 】分配: 【 6,2,1,0,0,0,1,0,0,0 】0在下排出现了6次,1在下排出现了2次,2在下排出现了1次,3在下排出现了...原创 2018-12-30 11:24:39 · 6634 阅读 · 4 评论 -
红黑树
关于红黑树的故事:如果被删的是红结点,那么没影响如果是黑结点,那么它死了,但它留下了它黑色的魂来支撑整个红黑树的结构,让这棵树暂时看起来合法。但毕竟这个魂是多余的,它需要附着在其它节点上,以至于有的点成了“双重黑”,于是需要不断地把这个黑魂往上挤,其间这个魂都是存在的,也就是说这棵树一直被你假装成合法的,直到这个黑魂被你挤出这棵树那么就真的合法了。以下是我个人的理解,我觉得还是将x路看原创 2013-06-09 14:09:40 · 1575 阅读 · 0 评论 -
啊哈!算法:三个算法问题(左旋转,大数据,变位词集)
无意中找到一本书《编程珠玑》,刚看到第二章,感觉作者讲解方式比较独特并且很有意思,在这里记录第二章的三个问题,以下是这三个问题。三个问题 A.给定一个包含32位整数的顺序文件,它至多包含40亿个这样的整数,并且整数的次序是随机的,请查找一个此文件中不存在的32位整数(至少必有一个遗漏,为什么?)。在有足够内存的情况下,你会如何解决这个问题?如果可以使用若干外部临时文件但可用主存却只有上...原创 2018-12-30 11:23:06 · 23807 阅读 · 0 评论 -
反转链表非递归/递归d
题目:输入一个链表的头结点,反转该链表,并返回反转后链表的头结点。(a)为链表,(b)为反转后的链表。假设当前指针为i,则我们需要将i->next=h.此时i和j之间会断裂,因此,我们需要另一个指针j去指示j的位置,同时i->next=h中的h也需要记录,因此,要反转一个链表需要用到3个指针同步向前遍历,基于这个思路,可以轻松写出下面的程序,唯一需要注意的是空指针的情况,越界的情况。原创 2013-09-07 16:20:34 · 1556 阅读 · 0 评论 -
360笔试题2013:牧师(传道士)与野人过河问题
文章转自:点击打开链接。在开头写上原创是由于我觉得绿色的标题比转载的灰色标题显眼(个人爱好),如果有对原作者冒犯,在此道歉。编程题、传教士人数M,野人C,M≥C,开始都在岸左边,①船只能载两人,传教士和野人都会划船,当然必须有人划船②两岸边保证野人人数不能大于传教士人数 把所有人都送过河,设计一方案,要求编程实现。 根据以往的一些经验,比如:走楼梯问题(一次可以走一步或者两原创 2013-09-08 21:36:58 · 6607 阅读 · 0 评论 -
时钟问题VS解不等式求交集
Tick and Tick Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7884 Accepted Submission(s): 2177 Problem DescriptionThe three ha...原创 2018-12-30 11:23:00 · 9626 阅读 · 0 评论 -
证明:一个有n个结点的非空二叉树的高度至少为lgn
题目:利用归纳法证明:一个有n个结点的非空二叉树的高度至少为证明:当n=1时,只有一个结点的二叉树的高度为0,成立。令有x个结点的二叉树的高度为h(x)假设当n=k,k>=2时,结论也成立,即有k个结点的非空二叉树的高度将n个结点的非空二叉树分成左子树k个结点和右子树n-k-1个结点,于是结点数为n的树高度由假设可知:当时,即时,故证。原创 2013-06-05 18:12:04 · 6341 阅读 · 0 评论 -
工场outing
工场outing创新工场家族成员每年会组织一次旅行,公司的hr为了安排旅行路线伤透脑筋, 因为公司party会场被安排到一个景点B, 而大家的宾馆被安排在了另-个景点A。而景点A和景点B之间有若干个景点No .. Ni。 每个旅游景点大家最多只玩一次. 同时每个旅游素点都有一个评分X, 景点之间会有公路相连, 大家都不喜欢走回头路. 所以每条公路只能走一次。 请帮助hr设计一条路线P,原创 2013-09-22 18:30:52 · 1483 阅读 · 0 评论 -
希尔(shell)排序-插入排序的扩展
希尔排序是插入排序的一种扩展和延伸.在希尔排序之前,有必要先说一下插入排序.插入排序的工作原理:1.从第2号元素开始扫描,直到最后一个元素.2.当扫描到i号元素的时候,假定前边0,1,2,3...i-1号元素都已经有序.用挖坑填数的方法,将A[i]号元素从数组中挖出来,保存在key中,依次比较A[i-1],A[i-2]....的值,如果都比key大,则后移,直到找到key的最终元素,就原创 2013-08-01 15:22:18 · 1502 阅读 · 0 评论 -
全排序vs八皇后问题vs三角八皇后
假设要求字符串/数组的全排序,例如:"123"的全排序,第1位有3种选择,第2位有2种选择,第3位1种选择,时间复杂度显然是3!.实际上容易知道,对于n个字符,全排序一共有n!种可能,是n!时间复杂度的.我们需要找一个算法求出所有的可能的排序,最好的办法是递归,如果选用循环,需要n层嵌套,不太现实.假设我们已经拥有一个函数 FullPermutation(A[n])能将数组A[n]全排序,于...原创 2018-12-30 11:25:17 · 19051 阅读 · 0 评论 -
2014UC的最后一道题题目:第一个只出现一次的字符[算法]
题目:在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。分析:这道题原本是2006年google的一道笔试题。这里UC加上了一个限制,就是不可以用for和while,本来这简直是一道送分题,当时教室热爆了,头脑也跟着发热,居然错掉了,实在是可惜,如果这里可以用for和while,那只需要用一个256大小的数组()就可以记录哪些元素不是第一次被访问的,问题就十分简原创 2013-10-14 21:04:35 · 1422 阅读 · 0 评论 -
根据前序遍历和中序遍历,重构出二叉树
题目:这道题目是一道面试题,先序遍历和中序遍历以数组的形式给出,要求我们根据这两个条件重构出二叉树。下图是一棵二叉树// 6// / \// 5 7 // / \ \// 2 4 8先序遍历:6,5,2,4,7,8中序...原创 2018-12-30 11:26:06 · 4391 阅读 · 0 评论 -
桶中取黑白球(编程之美)
原创 2013-10-26 14:41:33 · 1998 阅读 · 0 评论