随笔分类 -  算法

主要写一些平时遇到的有趣的算法问题
摘要:理解我接下来所说的东西,需要大家懂得简单的动态规划。KMP大家都不陌生了,但是其中计算next数组总是搞不明白,我想有很多人和我一样。所以这里用动态规划的思路去描述一下这个问题。模式串P=c[1]c[2]......c[n]先设几个符号:suffix(S): S的所有后缀的集合prefix(S): S的所有前缀的集合例如:suffix("abcd") = {"","d", "cd", "bcd"} prefix("abcd") = {"","a& 阅读全文
posted @ 2012-10-17 16:55 haolujun 阅读(4818) 评论(0) 推荐(0) 编辑
摘要:有N个数的数组,没有顺序。现在的问题是让你在数组中找出两个数,使得这两个数的和尽可能的接近0。想到的的方法是尝试所有数对的组合,之后找出其中和的绝对值最小的数对即可。但是这样做的时间复杂度是O(N^2),有没有更快一点的方法呢?这里给出一个O(NlogN)时间复杂度的算法。有一种比较直观的做法。对数组排好序之后。如果数字全部是正数,那么取最小的两个数的和。如果数字全部是负数,则取最大的两个数字的和。如果数字有正有负。那么我们必须枚举每一个xi,之后用二分在数组中找小于等于-xi的最大值和大于等于-xi的最小值。能与xi构成和的绝对值最小的数字,肯定就是这两个数字中的某一个。所有的xi都枚举过之 阅读全文
posted @ 2012-10-12 20:21 haolujun 阅读(5094) 评论(4) 推荐(1) 编辑
摘要:有编号1~100个灯泡,起初所有的灯都是灭的。有100个同学来按灯泡开关,如果灯是亮的,那么按过开关之后,灯会灭掉。如果灯是灭的,按过开关之后灯会亮。 现在开始按开关。 第1个同学,把所有的灯泡开关都按一次(按开关灯的编号: 1,2,3,......100)。第2个同学,隔一个灯按一次(按开关灯的编 阅读全文
posted @ 2012-10-10 21:31 haolujun 阅读(12754) 评论(2) 推荐(5) 编辑
摘要:话说,一个圆形池塘,鸭子在池塘里,狐狸在岸边,鸭子只有游到岸边才能飞走,而狐狸想吃鸭子,但是狐狸又不会游泳,只能在岸上跑。狐狸在岸上奔跑的速度是鸭子在水里游的速度的4倍,问鸭子怎样才能飞走而不被狐狸吃掉,假设狐狸足够聪明。 一个可行的想法是,鸭子在池塘里面游小圈,而狐狸在岸上跑大圈,但是被鸭子越落越 阅读全文
posted @ 2012-10-09 21:46 haolujun 阅读(2031) 评论(2) 推荐(0) 编辑
摘要:设r是f(x) = 0的根,选取x0作为r初始近似值,过点(x0,f(x0))做曲线y = f(x)的切线L,L的方程为y = f(x0)+f'(x0)(x-x0),求出L与x轴交点的横坐标 x1 = x0-f(x0)/f'(x0),称x1为r的一次近似值。过点(x1,f(x1))做曲线y = f(x)的切线,并求该切线与x轴交点的横坐标 x2 = x1-f(x1)/f'(x1),称x2为r的二次近似值。重复以上过程,得r的近似值序列,其中x(n+1)=x(n)-f(x(n))/f'(x(n)),称为r的n+1次近似值,上式称为牛顿迭代公式。下面利用牛顿迭代法求 阅读全文
posted @ 2012-09-26 20:25 haolujun 阅读(1324) 评论(0) 推荐(0) 编辑
摘要:n个人围成一个圈报数,每次报到m的人从圈中退出,后面的人之后从0重新开始报数。设X是淘汰前的每个人的位置编号,X'是淘汰后形成的新的位置编号X X'------------m -> 0m+1 -> 1m+2 -> 2m+3 -> 3... ->...n-1 -> n-1-m0 -> n-m1 -> n-m+12 -> n-m+2... -> ....m-2 -> n-2非常明显的对应关系:x'=(x-m)%nx =(x'+m)%n例如对于n=5,m=3,位置编号0,1,2,3,40 1 2 3 4 阅读全文
posted @ 2012-09-24 13:59 haolujun 阅读(233) 评论(0) 推荐(0) 编辑
摘要:把B用二进制表示:例如假如:B=101011B=2^5+2^3+2^1+2^0A^B = A^(2^5) * A^(2^3) * A^(2^1) * A^(2^0)= A^(2^5+2^3+2^1+2^0)=A^B所以可以从B的低位开始,循环并计算A^(2^0), A^(2^1), A^(2^2)....同时,并且判断B的该位是否为1,如果为1,把当前计算的A^(2^i)累乘到结果中。int Func(int a, int b){ int p = a; int ans = 1; while(b) { if(b & 1) ans = (ans * p... 阅读全文
posted @ 2012-09-24 10:37 haolujun 阅读(634) 评论(0) 推荐(0) 编辑
摘要:时空复杂度:冒泡排序:时间O(n^2),额外空间O(1)插入排序:时间O(n^2),额外空间O(1)选择排序:时间O(n^2),额外空间O(1)基数排序:时间O(k*n)(k=logN_max),额外空间O(n)(临时存储)+O(B)(记数,B为基的大小)记数排序:时间O(n+k),额外空间O(k)希尔排序:时间O(n*logn^2),额外空间O(1)快速排序:时间O(n*log(n)),额外空间O(logn)(递归栈)归并排序:时间O(n*log(n)),额外空间O(n)(临时数组)+O(logn)(递归栈)堆排序: 时间O(n*log(n))使快速排序退化的例子:n, n-1, n-2, 阅读全文
posted @ 2012-09-24 09:46 haolujun 阅读(601) 评论(0) 推荐(0) 编辑
摘要:设f(x)为1-x中各个数字每位上出现1的次数总和。假如X=a[k]*10^k + a[k-1]*10^(k-1) + ...... + a[1] * 10 + a[0]1: a[k] = 1f(x) = f(X-10^k) + (X-10^k) + f(10^k - 1)例如:f(1234) = f(234) + 234 + f(999)2: a[k] > 1f(X) = f(X-a[k]*10^k) + (a[k]-2)*f(10^k - 1) + f(2*10^k - 1)例如: f(4567) = f(567) + 2*f(999) + f(1999)这样我们就导出一个递推关系。 阅读全文
posted @ 2012-09-23 21:16 haolujun 阅读(316) 评论(0) 推荐(0) 编辑
摘要:序列1,2,3.....n,依次入栈,求有多少种不同的出栈序列Y^| .| ..| ...| ....| .....|...... ----------> X问题等价于从左下角(0, 0)到右上角(n, n),只能向右、向上走(向右代表入栈,向上代表出栈),并且x>=y的路径数目。很明显,结果为C(2n, n)-C(2n,n-1). 阅读全文
posted @ 2012-09-23 20:55 haolujun 阅读(720) 评论(0) 推荐(0) 编辑