随笔分类 -  Algorithm

摘要:https://www.cnblogs.com/yoyaprogrammer/p/delta_variance.html 阅读全文
posted @ 2019-10-18 18:28 freewater 阅读(511) 评论(0) 推荐(0)
摘要:1.递归实现int binarySearchRecursive(int a[],int low,int high,int key){ if(low>high) return -(low+1); int mid=low+(high-low)/2; if(key<a[mid]) return binarySearchRecursive(a,low,mid-1,key); else if(key > a[mid]) return binarySearchRecursive(a,mid+1,high,key); else ... 阅读全文
posted @ 2013-03-01 17:40 freewater 阅读(14080) 评论(1) 推荐(0)
摘要:今天的趣题来源于 IBM Ponder This 三月份的谜题。 大家应该都听说过这个老题目:有 1000 个一模一样的瓶子,其中有 999 瓶是普通的水,有一瓶是毒药。任何喝下毒药的生物都会在一星期之后死亡。现在,你只有 10 只小白鼠和一星期的时间,如何检验出哪个瓶子里有毒药? 这个问题的答案也堪称经典:把瓶子从 0 到 999 依次编号,然后全部转换为 10 位二进制数。让第一只老鼠喝掉所有二进制数右起第一位是 1 的瓶子,让第二只老鼠喝掉所有二进制数右起第二位是 1 的瓶子,等等。一星期后,如果第一只老鼠死了,就知道毒药瓶子的二进制编号中,右起第一位是 1 ;如果第二只老鼠没死,就知道 阅读全文
posted @ 2012-10-10 09:46 freewater 阅读(479) 评论(0) 推荐(0)
摘要:一、知识简介 最近在看字符串算法了,其中字典树、AC自动机和后缀树的应用是最广泛的了,下面将会重点介绍下这几个算法的应用。字典树(Trie)可以保存一些字符串->值的对应关系。基本上,它跟 Java 的 HashMap 功能相同,都是 key-value 映射,只不过 Trie 的 key 只能是字符串。 Trie 的强大之处就在于它的时间复杂度。它的插入和查询时间复杂度都为 O(k) ,其中 k 为 key 的长度,与 Trie 中保存了多少个元素无关。Hash 表号称是 O(1) 的,但在计算 hash 的时候就肯定会是 O(k) ,而且还有碰撞之类的问题;Trie 的缺点是空间消耗 阅读全文
posted @ 2012-09-11 16:59 freewater 阅读(790) 评论(0) 推荐(0)
摘要:这篇博客母函数讲解的非常好!在数学中,某个序列的母函数(Generating function,又称生成函数)是一种形式幂级数,其每一项的系数可以提供关于这个序列的信息。使用母函数解决问题的方法称为母函数方法。母函数可分为很多种,包括普通母函数、指数母函数、L级数、贝尔级数和狄利克雷级数。对每个序列都可以写出以上每个类型的一个母函数。构造母函数的目的一般是为了解决某个特定的问题,因此选用何种母函数视乎序列本身的特性和问题的类型。这里先给出两句话,不懂的可以等看完这篇文章再回过头来看:1.“把组合问题的加法法则和幂级数的乘幂对应起来”2.“母函数的思想很简单 — 就是把离散数列和幂级数一 一对应 阅读全文
posted @ 2012-09-11 10:12 freewater 阅读(3414) 评论(0) 推荐(0)
摘要:今天在学习《程序员实用算法》时,看到了单链表快排序这一节。初看时感觉程序有很大的问题,但是细细品味之后却发现程序设计的极为巧妙,同时又深感自己C语言指针知识之不牢固,特别是指针的指针方面的知识。单链表的快排序和数组的快排序基本思想相同,同样是基于划分,但是又有很大的不同:单链表不支持基于下标的访问。故书中把待排序的链表拆分为2个子链表。为了简单起见,选择链表的第一个节点作为基准,然后进行比较,比基准大节点的放入左面的子链表,比基准大的放入右边的子链表。在对待排序链表扫描一遍之后,左面子链表的节点值都小于基准的值,右边子链表的值都大于基准的值,然后把基准插入到链表中,并作为连接两个子链表的桥梁。 阅读全文
posted @ 2012-09-09 14:02 freewater 阅读(655) 评论(0) 推荐(0)
摘要:/* 基本算法描述: 给出一个字符串abababa 1.穷举出所有的后缀子串 substrs[0] = abababa; substrs[1] = bababa; substrs[2] = ababa; substrs[3] = baba; substrs[4] = aba; substrs[5] = ba; substrs[6] = a; 2.然后进行比较 substrs[0]比substrs[1]多了一个字母,如果说存在连续匹配的字符,那... 阅读全文
posted @ 2012-09-07 22:17 freewater 阅读(1669) 评论(0) 推荐(0)
摘要:1、实现一个函数,对一个正整数n,算得到1需要的最少操作次数。操作规则为:如果n为偶数,将其除以2;如果n为奇数,可以加1或减1;一直处理下去。例子:func(7) = 4,可以证明最少需要4次运算n = 7n-1 6n/2 3n-1 2n/2 1要求:实现函数(实现尽可能高效) int func(unsign int n);n为输入,返回最小的运算次数。给出思路(文字描述),完成代码,并分析你算法的时间复杂度。答:int func(unsigned int n){ if(n == 1) return 0; if(n % 2 == 0) return 1... 阅读全文
posted @ 2012-08-26 16:49 freewater 阅读(1185) 评论(0) 推荐(0)
摘要:一、题目概述:有一个没有排序,元素个数为2N的正整数数组。要求把它分割为元素个数为N的两个数组,并使两个子数组的和最接近。假设数组A[1..2N]所有元素的和是SUM。模仿动态规划解0-1背包问题的策略,令S(k, i)表示前k个元素中任意i个元素的和的集合。显然:S(k, 1) = {A[i] | 1<= i <= k}S(k, k) = {A[1]+A[2]+…+A[k]}S(k, i) = S(k-1, i) U {A[k] + x | x属于S(k-1, i-1) }按照这个递推公式来计算,最后找出集合S(2N, N)中与SUM最接近的那个和,这便是答案。这个算法的时间复杂 阅读全文
posted @ 2012-08-23 19:18 freewater 阅读(10899) 评论(0) 推荐(0)
摘要:十一、从头到尾彻底解析Hash 表算法作者:July、wuliming、pkuoliver出处:http://blog.csdn.net/v_JULY_v。说明:本文分为三部分内容, 第一部分为一道百度面试题Top K算法的详解;第二部分为关于Hash表算法的详细阐述;第三部分为打造一个最快的Hash表算法。------------------------------------第一部分:Top K 算法详解问题描述百度面试题: 搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节。 假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万 阅读全文
posted @ 2012-08-22 15:20 freewater 阅读(741) 评论(0) 推荐(0)
摘要:作者:小飞 原文地址:http://yishan.cc/blogs/nickledson/archive/2008/12/29/997.aspx 《编程之美》一书上有一道题:给定一个由N个整数元素组成数组a,写一个函数在其中找出连续子数组和的最大值。例如给定数组为{1, -2, 3, 5, -1, 2},则和最大的连续子数组是{3, 5, -1, 2},函数返回值是9。 这是一道典型的动态规划问题,书中循序渐进地通过分析给出了一个时间复杂度为O(N)空间复杂度为O(1)的最优解。我在面试时碰到了这道题的一道有趣变体,即同样给定一个数组,写一个在其中找出不连续子数组和的最大值,也就是说子数组.. 阅读全文
posted @ 2012-08-18 20:32 freewater 阅读(3183) 评论(0) 推荐(0)
摘要:int comlen(const char* str1,const char* str2){ assert((str1!=0)&&(str2!=0)); int len=0; while(*str1!='\0'&&*str2!='\0'&&*str1++==*str2++){ len++; } return len;}bool less(char* str1,char* str2){ return strcmp(str1,str2)<=0;}/*后缀数组法*/void longestRepeatedSubst 阅读全文
posted @ 2012-08-13 20:39 freewater 阅读(261) 评论(0) 推荐(0)
摘要:1 public static void insertSort(int[] a){ 2 for(int j=1;j<a.length;j++){ 3 int key=a[j]; 4 int i=j-1; 5 while(i>=0&&key<a[i]){ 6 a[i+1]=a[i]; 7 i--; 8 } 9 a[i+1]=key; 10 } 11 } 1... 阅读全文
posted @ 2012-08-13 20:08 freewater
摘要:问题描述:程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内的m个随机整数,要求:每个数选择出现的概率相等,且按序输出。该题目是从《编程珠玑》的第12章看到的。 学习过概率统计的同学应该都知道每一个数字被抽取的概率都应该为m/n. 那么我们怎么构造出这样的概率呢?在《编程珠玑》上面是这样解析的: 依次考虑整数0,1,2,.....,n-1,并通过一个适当的随机测试对每个整数进行选择。通过按序访问整数,我们可以保证输出结果是有序的。 假如我们考虑m = 2,n = 5的情况,那么选择的每一个数字的概率都应该是2/5,我们怎么样才能做到呢?不慌张,慢慢来。 下面给出我的分析过程 阅读全文
posted @ 2012-08-12 21:33 freewater 阅读(319) 评论(0) 推荐(1)
摘要:/*qsort1至qsort3都是同一种思路,只是变换了不变式invariant罢了*//*分割点a[u].invariant:a[l,m)<t && a[m,i)>=t, for each i in [l,u)*/void qsort1(int a[],int l,int u){ if(l>=u) return; int m=l; for(int i=l;i<u;i++){ if(a[i]<a[u]){ //a[i]<->a[m]; swap(a[i],a[m]); m++; ... 阅读全文
posted @ 2012-08-12 21:06 freewater 阅读(182) 评论(0) 推荐(0)
摘要:/*方案一:每次循环左移一位,移动k次。*/void rol(char str[],int n,int k){ assert(k<=n);//assume k is less than n, otherwise we can let k=k%n to meet this requirement. char tmp; for(int i=0;i<k;i++){ tmp=str[0]; memcpy(str,str+1,n-1); str[n-1]=tmp; }}/*方案二:将前k个数拷贝到临时数组中,然后移动后n-k个,再将前k个... 阅读全文
posted @ 2012-08-01 21:59 freewater 阅读(399) 评论(0) 推荐(0)
摘要:辗转相除法int gcd1(int x,int y){ if(y==0) return x; else return gcd1(y,x%y);}但是取模运算的开销很大,可以考虑使用x-y替代,因为x,y,x-y一定具有相同的最大公约数。int gcd2(int x,int y){ if(x<y) return gcd2(y,x); if(y==0) return x; else return gcd2(y,x-y);}编程之美2.7节又提供了两种方法结合。gcd(x,y)=gcd(p*x1,y)... 阅读全文
posted @ 2012-07-18 20:49 freewater 阅读(298) 评论(0) 推荐(0)
摘要://输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数, 使其和等于 m ,要求将其中所有的可能组合列出来.//n=10, m=9output:/*9 18 27 37 2 16 46 3 15 4 15 3 24 3 2 1*/vector<int> factors; 1 void findFactor2(int sum,int n){ 2 if(sum<0||n<0) 3 return ; 4 if(sum==0){ 5 for(vector<int>::iterator iter=factors.begin();i... 阅读全文
posted @ 2012-07-16 10:55 freewater 阅读(1968) 评论(0) 推荐(0)
摘要:递归生成排列和组合 1 void doPermute(char str[],char result[],bool used[],int length,int level){ 2 if(level==length){ 3 cout<<result<<endl; 4 return; 5 } 6 7 for(int i=0;i<length;i++){ 8 if(!used[i]){ 9 result[level]=str[i];10 used[i]=true;11 ... 阅读全文
posted @ 2012-07-15 23:19 freewater 阅读(242) 评论(0) 推荐(0)
摘要:题目:n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始,每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。当一个数字删除后,从被删除数字的下一个继续删除第m个数字。求出在这个圆圈中剩下的最后一个数字。分析:本题就是有名的约瑟夫环问题。既然题目有一个数字圆圈,很自然的想法是我们用一个数据结构来模拟这个圆圈。在常用的数据结构中,我们很容易想到用环形列表。我们可以创建一个总共有m个数字的环形列表,然后每次从这个列表中删除第m个元素。在参考代码中,我们用STL中std::list来模拟这个环形列表。由于list并不是一个环形的结构,因此每次跌代器扫描到列表末 阅读全文
posted @ 2012-07-15 21:25 freewater 阅读(356) 评论(0) 推荐(0)