05 2012 档案

字符串的排列组合问题
摘要:来源http://blog.csdn.net/wuzhekai1985问题1 :输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则输出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。 思路:这是个递归求解的问题。递归算法有四个特性:(1)必须有可达到的终止条件,否则程序将陷入死循环;(2)子问题在规模上比原问题小;(3)子问题可通过再次递归调用求解;(4)子问题的解应能组合成整个问题的解。 对于字符串的排列问题。如果能生成n - 1个元素的全排列,就能生成n个元素的全排列。对于只有1个元素的集合,可以直接生成全排列。全排列的递归终止 阅读全文

posted @ 2012-05-30 17:00 为梦飞翔 阅读(10475) 评论(4) 推荐(2)

求一个数组的最长递减子序列 比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,4,3,2}
摘要:目前想到的一个方法,就是用栈来寻找,说下思想:(栈中的data为元素所在的位置,这意味着出栈和进栈的都是索引值,所以比较的时候根据索引找到其值后比较)(1)栈为空,把一个元素入栈。9(2)把小于栈顶的元素依次入栈。9 4 3 2,入栈完成后记录一下该组合(3)若栈为空,结束,非空,则出栈,寻找小于栈顶值大于出栈值的元素,出栈后当栈为空时,找到一个比弹出元素大的即可。(开始查找的位置出栈值所在位置的后一个)(4)若找到,则把该元素入栈,跳到步骤(2)(5)若找不到,则继续步骤(3)(6)其中组合最大的即为所求模拟一下该过程9(1)9 4 3 2(2)9 4 3(3)(5)9 4(3)(5)9 5 阅读全文

posted @ 2012-05-30 11:14 为梦飞翔 阅读(2183) 评论(2) 推荐(0)

四对括号可以有多少种匹配排列方式?比如两对括号可以有两种:()()和(())
摘要:该题的公式版暂时还没弄出来,感觉是应该可以按照排列组合弄出来的。下面给出程序版的第一种思想:把所有8位以内的二进制数循环一次,对于每一个二进制数的每一位,从高到低依次相加,其中遇到0的话加-1,遇到1加1,每次加的结果需要大于等于0加完所有位的结果应该为0,满足两个条件的即是一种组合第二种思想:我们可以用生成二叉树的方法解决,重新定义一个数据结构,数据结构如下:struct Node{ int data;//0或1 int num0;//0出现的次数 int num1;//1出现的次数 struct Node* lchild; struct Node* rchil... 阅读全文

posted @ 2012-05-30 10:06 为梦飞翔 阅读(2813) 评论(2) 推荐(0)

显示一个序列中和等于10的所有组合
摘要:这个题的扩展应用很多,虽然下面运算的复杂度很高,但是其思想非常巧妙,借助位运算实现了所有可能的组合,关键是该思想值得借鉴,在没有比较好的方法的情况下,我们就需要一个个来试,但是要一个不漏的把所有情况都考虑到一般的方法很麻烦下面就详细介绍一下该算法的思想:(1)首先根据序列的长度确定组合数,如长度为8则最大的组合只可能是8(2)从1到1<<8中每一个数的等于1的位就代表一种组合,我们把这种组合对应的数相加,看其是否等于所求的值,如何是就输出对应位的值该算法显然可以再进行优化,但是其依然很难在大数据面前有效首先就是循环的次数上,如果序列的长度是n,则需要查找的次数为2n-1,指数倍的增 阅读全文

posted @ 2012-05-29 11:51 为梦飞翔 阅读(830) 评论(0) 推荐(0)

在从1到n的正数中1出现的次数
摘要:题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次。分析:这是一道广为流传的google面试题。简单的方法就是按照给位进行分析在个位出现1的个数=n/10+(个位=0,0;个位>1,1;个位=1,低0位+1);十位位出现1的个数=n/100*10+(十位=0,0;十位>1,10,;十位=1,低一位+1);百位出现1的个数=n/1000*100+(百位=0,0;百位>1,100;百位=1,低两位+1);等等算法的复杂度仅仅和位数有关算法描述:(1)求出所给正整数a的位数, 阅读全文

posted @ 2012-05-28 15:40 为梦飞翔 阅读(4653) 评论(0) 推荐(0)

栈的push、pop序列
摘要:题目:输入两个整数序列。其中一个序列表示栈的push顺序,判断另一个序列有没有可能是对应的pop顺序。为了简单起见,我们假设push序列的任意两个整数都是不相等的。比如输入的push序列是1、2、3、4、5,那么4、5、3、2、1就有可能是一个pop系列。因为可以有如下的push和pop序列:push 1,push 2,push 3,push 4,pop,push 5,pop,pop,pop,pop,这样得到的pop序列就是4、5、3、2、1。但序列4、3、5、1、2就不可能是push序列1、2、3、4、5的pop序列。基本思路:(1)用两个指针分别指向数组的头部,pPush,pPop;(2) 阅读全文

posted @ 2012-05-28 12:41 为梦飞翔 阅读(1783) 评论(0) 推荐(0)

左旋转字符串
摘要:题目:定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。如把字符串abcdef左旋转2位得到字符串cdefab。请实现字符串左旋转的函数。要求时间对长度为n的字符串操作的复杂度为O(n),辅助内存为O(1)。思路:把字符串看出两个XY(XTYT)T=YXXT为X的旋转操作 1 void inverse(char* start,char* end){ 2 while(start<end){ 3 char temp=*start; 4 *start=*end; 5 *end=*start; 6 start++... 阅读全文

posted @ 2012-05-28 10:15 为梦飞翔 阅读(279) 评论(0) 推荐(0)

Fibonacci序列or兔子序列
摘要:题目:定义Fibonacci数列如下: / 0 n=0f(n)= 1 n=1 / f(n-1)+f(n-2) n=2输入n,用最快的方法求该数列的第n项。分析:在很多C语言教科书中讲到递归函数的时候,都会用Fibonacci作为例子。因此很多程序员对这道题的递归解法非常熟悉,但....呵呵,你知道的。。这个一种O(n)复杂度的就是int a=0,b=1,c;for(int i=2;i<=n;i++){ c=a+b; a=b; b=c;}printf c;另外一个更牛的这还不是最快的方法。下面介绍一种时间复杂度是O(logn)的方法。在介绍这种方法之前,先介绍一个数学公式:{f(n)... 阅读全文

posted @ 2012-05-25 22:41 为梦飞翔 阅读(1155) 评论(0) 推荐(0)

约瑟夫环问题
摘要:题目:n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始,每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。当一个数字删除后,从被删除数字的下一个继续删除第m个数字。求出在这个圆圈中剩下的最后一个数字。这个问题数学上已经得出了递推公式递推公式: f[1]=0; f[i]=(f[i-1]+m)%i; (i>1)当然我们就不推了,这里给出一个中规中矩的用环的方法来解决此问题 1 Node* Josephus(Node* Head,int m){ 2 Node* p=Head; 3 while(true){ 4 ... 阅读全文

posted @ 2012-05-25 20:32 为梦飞翔 阅读(261) 评论(0) 推荐(0)

题目:输入一颗二元查找树,将该树转换为它的镜像,
摘要:即在转换后的二元查找树中,左子树的结点都大于右子树的结点。用递归和循环两种方法完成树的镜像转换。 例如输入: 8 / / 6 10// //5 7 9 11输出: 8 / /10 6// //11 9 7 5定义二元查找树的结点为:struct BSTreeNode // a node in the binary search tree (BST){ int m_nValue; // value of node BSTreeNode *m_pLeft; // left child of node BSTreeNode *m_pRight; // right child of node};分析: 阅读全文

posted @ 2012-05-25 17:26 为梦飞翔 阅读(509) 评论(0) 推荐(0)

题目:输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。
摘要:要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字M,输出任意一对即可。例如输入数组1、2、4、7、11、15和数字15。由于4+11=15,因此输出4和11。思路:(1)让指针指向数组的头部和尾部,相加,如果小于M,则增大头指针,如果大于则减小尾指针(2)退出的条件,相等或者头部=尾部算法:void function(int a[],int n,int M){ int i=0,j=n-1; while(i!=j){ if(a[i]+a[j]==M){ printf("%d,%d",a[i],a[j]); break; } a[i]+a... 阅读全文

posted @ 2012-05-25 17:01 为梦飞翔 阅读(7186) 评论(0) 推荐(0)

求1+2+…+n,
摘要:要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。方法:从递归下手一般是这样的int sum(int n){ if(n==0) return 0; return n+sum(n-1);}把上述稍加改动即可int sum(int n){ return n&&(n+sum(n-1));} 阅读全文

posted @ 2012-05-25 16:23 为梦飞翔 阅读(275) 评论(0) 推荐(0)

二叉树的直径
摘要:基本思路:(1)求每个节点左右子树的深度,则进过该节点的最大length=ldeep+rdeep;(2)取最大的length即为二叉树的直径当然这个算法性能不好,但思路很简单,这次也采用递归算法,如果要求采用非递归的话,首先需要改动的是TreeDeep,然后FindMax这个实际上市递归遍历每个节点,可以用遍历的非递归形式替换即可。(如果有人想要看非递归又不会,给我留言,我就添加上)这个问题一个延伸,就是输出最长路径给出一个思路抛砖引玉:在FindMaxLen函数外面添加一个全局变量BitTree finalroot;修改MaxLen=处的代码为if(temp>MaxLen){ MaxL 阅读全文

posted @ 2012-05-25 14:08 为梦飞翔 阅读(2940) 评论(1) 推荐(1)

翻转句子中单词的顺序
摘要:题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。例如输入“I am a student.”,则输出“student. a am I”。思路:先反整个句子,再反转每个单词输出 阅读全文

posted @ 2012-05-25 12:59 为梦飞翔 阅读(278) 评论(0) 推荐(0)

判断整数序列是不是二元查找树的后序遍历结果
摘要:这个其实很简单(1)首先把给出的序列从小到大排列,这相当于是一个中序遍历的结果(2)有中序遍历和后续遍历重构二叉树(3)判断二叉树是否是二元查找树二元查找树: 它首先要是一棵二元树,在这基础上它或者是一棵空树;或者是具有下列性质的二元树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值; (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值; (3)左、右子树也分别为二元查找树 阅读全文

posted @ 2012-05-24 21:57 为梦飞翔 阅读(333) 评论(0) 推荐(0)

查找最小的k个元素
摘要:题目:输入n个整数,输出其中最小的k个。例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4。思路:取K歌元素,找出最大值,然后与第K+1个比较,若大于第K+1个,则被替换,否则丢弃第K+1个(1)在数组中前K个的最大值,与K+1个比较,若大于第K+1个,最大值被替换,否则丢弃K+1个(2)接着K+i等等(3)结束后前K个技术最小值 阅读全文

posted @ 2012-05-24 20:08 为梦飞翔 阅读(242) 评论(0) 推荐(0)

微软面试4、在二元树中找出和为某一值的所有路径
摘要:题目:输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。例如 输入整数22和如下二元树 10 / / 5 12 / / 4 7则打印出两条路径:10, 12和10, 5, 7。思路1:(这个感觉不是最好的,看到的欢迎分享新方法)后续遍历二叉树,同时用一个变量sum记录栈中所有节点的和,当节点输出时,判断该节点是否是叶子节点,同时sum是否是目标和若两者均满足,则测试栈中的元素即是一条路径。代码: 1 View Code 2 void PathSum(BiTree BT,int SUM){ 3 St... 阅读全文

posted @ 2012-05-24 16:00 为梦飞翔 阅读(245) 评论(0) 推荐(0)

微软面试题2、设计包含min函数的栈
摘要:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。思路:其数据结构如下Struct LinkNode{ DataType data; Struct LinkNode * next; Struct LinkNode * pMin;};第一个节点入栈的时候若为空,p->next=NULL;p->pMin=p;第二个节点入栈的时候,首先和栈顶元素pHead->pMin->data比较大小,若当前节点不大于它,则p->pMin=p否则,p->pMin=pHead->pMin; 阅读全文

posted @ 2012-05-24 14:52 为梦飞翔 阅读(160) 评论(0) 推荐(0)

微软面试题1、把二元查找树转变成排序的双向链表
摘要:题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。 10 / /6 14/ / / /4 8 12 16转换成双向链表4=6=8=10=12=14=16。首先我们定义的二元查找树 节点的数据结构如下:struct BSTreeNode{ int m_nValue; // value of node BSTreeNode *m_pLeft; // left child of node BSTreeNode *m_pRight; // right child of node};基本思路1:(这个有新节点,用递归,见思路2)中序遍历二叉树, 阅读全文

posted @ 2012-05-24 14:10 为梦飞翔 阅读(446) 评论(0) 推荐(0)

读取文件的最后N行 问题思路来自 http://www.cnblogs.com/cobbliu/archive/2012/03/10/2388802.html
摘要:思路两个:(1)快慢指针,和找链表倒数第K个节点有点类似。同样适用两个文件指针,fp,fs,把快的文件指针先读N行后,快慢文件指针同时一行一行的开始读取,直到快的文件指针读到文件最后,则慢的文件指针此时读到文件的倒数第N行,就可以开始数数慢的文件指针的内容直到读取文件结束。 1 void PrintfFileN(string filename,int n){ 2 File* fp,*fs; 3 int i; 4 char fpline[MAXLINE]; 5 char fsline[MAXLINE]; 6 if((fp = fopen(file... 阅读全文

posted @ 2012-05-24 12:35 为梦飞翔 阅读(681) 评论(0) 推荐(0)

关于常见排序算法稳定性分析和结论 转自http://hi.baidu.com/cuifenghui/blog/item/0587932b039557f9e7cd4051.html
摘要:关于常见排序算法的稳定性分析和结论2007-10-16 9:25 这几天笔试了好几次了,连续碰到一个关于常见排序算法稳定性判别的问题,往往还是多选,对于我以及和我一样拿不准的同学可不是一个能轻易下结论的题目,当然如果你笔试之前已经记住了数据结构书上哪些是稳定的,哪些不是稳定的,做起来应该可以轻松搞定。本文是针对老是记不住这个或者想真正明白到底为什么是稳定或者不稳定的人准备的。 首先,排序算法的稳定性大家应该都知道,通俗地讲就是能保证排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同。在简单形式化一下,如果Ai = Aj, Ai原来在位置前,排序后Ai还是要在Aj位置前。 阅读全文

posted @ 2012-05-24 09:54 为梦飞翔 阅读(202) 评论(0) 推荐(0)

删除链表中指定节点,要求时间复杂度为O(1)
摘要:思路:(1)把要删除的节点的值与其next交换(2)删除其next(3)完成算法: 1 void DeleteNode(LinkList *p){ 2 if(p->next=NULL){ 3 free(p); 4 p=NULL; 5 }else{ 6 LinkList* lk=p->next; 7 int temp=p->data; 8 p->data=lk->data; 9 lk->data=temp;10 p->next=lk->next... 阅读全文

posted @ 2012-05-24 09:40 为梦飞翔 阅读(866) 评论(0) 推荐(0)

查找单向链表中倒数第K个节点
摘要:基本思路:(1)将pSlow和pFast同时指向链表的头部(2)将快指针向后移动K位(3)快慢指针同时移动,当pFast为空时,pSlow就指向倒数第K个节点(4)结束算法: 1 LinkList* FindK(LinkList* LK,int K){ 2 LinkList *pSlow,*pFast; 3 pSlow=pFast=LK; 4 int i=0; 5 while(i<K){ 6 pFast=pFast->next; 7 i++; 8 } 9 while(pFast){10 pSlow=... 阅读全文

posted @ 2012-05-24 09:20 为梦飞翔 阅读(344) 评论(0) 推荐(0)

两个有序链表的合并
摘要:思想: 1 LinkList * merge(LinkList* HeadA,LinkList* HeadB){ 2 LinkList* HeadC=NULL,*last=NULL; 3 while(HeadA!=NULL&&HeadB!=NULL){ 4 if(HeadA->data<HeadB->data) 5 { 6 if(HeadC==NULL) 7 HeadC=last=HeadA; 8 else 9 {10 last->next=HeadA;11 last=Head... 阅读全文

posted @ 2012-05-23 22:57 为梦飞翔 阅读(288) 评论(0) 推荐(0)

由一棵二叉树的先序序列和中序序列可唯一确定这棵二叉树
摘要:思路:(1)由先序可以得到树的根节点。(2)由中序可以得到左右子树。(3)重复(1)(2)即可恢复同理给出后续和中序也可以按照上述思想唯一确定一棵树(这个程序转的http://www.cnblogs.com/microgrape/archive/2011/05/12/2043932.html) 1 #include <iostream> 2 #include <map> 3 #include <utility> 4 #include <functional> 5 #include <string> 6 #include <sta 阅读全文

posted @ 2012-05-23 17:15 为梦飞翔 阅读(4790) 评论(0) 推荐(0)

如何判断一颗二叉树为完全二叉树
摘要:基本思想:(1)若跟节点非空,则入队。(2)让p指向队列的对头,若p为NULL,则遍历队列的所有元素,如果出现非空值则返回false,否则返回true(3)若P非空,则将p的左右孩子入队,然后将P出队(这个地方可以在获取p的时候进行出队也行,另外入队的节点不论空与否都会进入)(4)重复步骤(2)(3)直到队列为空(5)结束算法 1 bool ComBinTree(BinTree BT){ 2 Queue Q; 3 if(BT!=NULL) 4 EnQueue(Q,BT); 5 while(!isEmptyQueue(Q)){ 6 Bi... 阅读全文

posted @ 2012-05-23 16:33 为梦飞翔 阅读(662) 评论(0) 推荐(0)

如何复制一棵二叉树
摘要:基本思路:(1)如果树非空,则复制该根节点,同时,把这两个节点分别进入QueueFormer,QueueCopy(2)让pFormer指向QueueFormer的对头,pCopy指向QueueCopy的队头。(3)pFormer的左右孩子,若非空,则复制其data,同时修改pCopy的左右孩子的指针,并对非空节点都入站操作,(4)对QueueFormer和QueueCopy出栈(对头节点已完成复制)(5)重复(2)~(4)直到队列为空(6)返回头指针,复制完成。代码: 1 BinTree CopyTree(BinTree BT){ 2 Queue QueueFormer; 3 ... 阅读全文

posted @ 2012-05-23 14:05 为梦飞翔 阅读(5668) 评论(0) 推荐(0)

二叉树交换左右子树非递归算法
摘要:基本思想:(先序,中序,后序,层次遍历都可以实现,本质就是就是交换每个节点的左右孩子)(1)若树非空,则入队(2)若队头指针的左右孩子非空,则入队。(3)交换对头节点的左右孩子,出队。(4)重复步骤(2)(3)直到队列为空(5)交换结束。算法: 1 void Exchange(BinTree BT){ 2 Queue Q; 3 initQueue(Q); 4 if(BT!=NULL){ 5 EnQueue(Q,BT); 6 } 7 while(!isEmptyQueue(Q)){ 8 BinTree p=QueueHead... 阅读全文

posted @ 2012-05-23 10:57 为梦飞翔 阅读(6596) 评论(0) 推荐(1)

如何判断两个链表是否相交,以及交点
摘要:基本思路1:链表1,2均没有环把链表1首尾相连,判断链表2是否有环,若有环,则相交。基本思路2:遍遍历链表1,2,若尾指针相等,则相交。如何就交点:链表1和链表2的长度想减求绝对值,较长的链表先移动差值个位置,然后两个链表同时移动,相等的地方即为交点。算法也不给出了 阅读全文

posted @ 2012-05-23 10:19 为梦飞翔 阅读(961) 评论(0) 推荐(0)

如何判断链表是否有环
摘要:基本思想:使用快慢指针,慢指针每次向后移动一个位置,快指针每次移动两个位置。这样如果没环,快指针或快指针的next先为空,返回false若有环,快指针一定可以追上慢指针,即两者会相等,则返回true代码 1 bool HaveHuan(ListNode LN){ 2 ListNode p=LN; 3 ListNode pSlow=pFast=p; 4 while(pFast!=NULL&&pFast->next!=NULL){ 5 pSlow=pSlow->next; 6 pFast=pFast->next->next; 7 ... 阅读全文

posted @ 2012-05-23 10:12 为梦飞翔 阅读(398) 评论(0) 推荐(0)

链表的倒序算法
摘要:基本思路1:pNext=p->next;p->next=pFormer;pFormer=p;p=pNext;算法: 1 LinkNode function(LinkNode LN){ 2 LinkNode p=LN; 3 LinkNode pFormer=NULL,pNext; 4 while(p!=NULL){ 5 pNext=p->next; 6 p->next=pFormer; 7 pFormer=p; 8 p=pNext; 9 }10 return pFormer;11 }基本思路2... 阅读全文

posted @ 2012-05-22 22:50 为梦飞翔 阅读(4968) 评论(0) 推荐(0)

二叉树层次遍历算法+非递归
摘要:基本思路:(1)若树节点非空,则入队。(2)把对头的左右节点入队(非空),出队(并输出结果)(3)重复步骤(2)直到对为空算法: 1 void LayerTraverse(BinTree BT){ 2 Queue Q; 3 BinTree p=BT; 4 if(p!=NULL){ 5 EnQueue(Q,p); 6 } 7 while(!IsEmpty(Q)){ 8 p=DeQueue(Q); printf("%c",p->data);9 if(p->lchild!=NULL) 10 ... 阅读全文

posted @ 2012-05-22 22:25 为梦飞翔 阅读(5706) 评论(0) 推荐(0)

二叉树的深度,递归和非递归实现
摘要:递归实现基本思想:为了求得树的深度,可以先求左右子树的深度,取二者较大者加1即是树的深度,递归返回的条件是若节点为空,返回0算法:1 int FindTreeDeep(BinTree BT){2 int deep=0;3 if(BT){4 int lchilddeep=FindTreeDeep(BT->lchild);5 int rchilddeep=FindTreeDeep(BT->rchild);6 deep=lchilddeep>=rchilddeep?lchilddeep+1:rchilddeep+1;7 ... 阅读全文

posted @ 2012-05-22 20:57 为梦飞翔 阅读(30197) 评论(0) 推荐(7)

二叉树的后续非递归遍历
摘要:void TraverseTree(BTree BT){ StackTree S; StackTag tag; BTree p=BT; while (p!=NULL||!IsEmpty(S)) { while (p) { push(S,p); push(tag,0); p=p->pLchild; } if (Top(S)->pRchild==NULL||Top(tag)==1) { BTree temp=P... 阅读全文

posted @ 2012-05-22 17:54 为梦飞翔 阅读(1290) 评论(0) 推荐(1)

[zz http://www.cnblogs.com/oldfeel/archive/2012/05/15/2501290.html] android 录像/打开video文件
摘要:先建立录像窗口 map_video.xml<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <SurfaceView android:id=&quo 阅读全文

posted @ 2012-05-15 21:28 为梦飞翔 阅读(1061) 评论(2) 推荐(0)

导航