编程算法
文章平均质量分 78
linyunzju
这个作者很懒,什么都没留下…
展开
-
跳转表 skip lists
跳转表是动态平衡数据结构( balanced dynamic search structure )的一种, 动态平衡数据结构还包括AVL树,2-3-4数,B数,红黑树,Treaps等. 跳转表由William Pugh在1989年创造,相对其他动态平衡数据结构,它具有容易编码实现的优点. 跳转表的一次操作(包括某个元素的插入,删除和查找)绝大多数情况下能够在O(lgn)原创 2012-05-31 16:04:45 · 4902 阅读 · 0 评论 -
编程之美2.6——精确表达浮点数
问题:用分数形式来表示小数,以达到精确的计算结果。 解答一:用于小整数,将无限循环小数0.a1a2...an(b1b2...bm)分为非循环部分和循环部分。X=((a1a2...an)*(10^m-1)+b1b2...bm)/((10^m-1)*10^n)#include using namespace std;long long gcd(long long原创 2012-06-29 21:52:12 · 1665 阅读 · 0 评论 -
编程之美2.19——区间重合判断(线段树)
问题:1. 给定一个源区间[x,y]和N个无序的目标区间[x1,y1] [x2,y2] ... [xn,yn],判断源区间[x,y]是不是在目标区间内。2. 给定一个窗口区域和系统界面上的N个窗口,判断这个窗口区域是否被已有的窗口覆盖。1. 解法:先用区间的左边界值对目标区间进行排序O(nlogn),对排好序的区间进行合并O(n),对每次待查找的源区间,用二分查出其左右两边原创 2012-07-11 22:43:48 · 5707 阅读 · 2 评论 -
编程之美3.1——字符串移位包含的问题(KMP算法)
问题:给定两个字符串s1和s2,要求判定s2是否能够被s1做循环移位得到的字符串包含。解法:我们在对s1进行循环移位时,保留前面移走的数据,会发现只要将s1复制一份接在后面就能够包含匹配的所有情况。然后只要在s1中查找s2的位置就可以了,我们使用KMP算法在时间O(m+n)内就能够找出这个位置。KMP算法还是一个比较难理解的算法之一,它的改进在于每当一趟匹配过程中出现字符比原创 2012-07-14 14:29:48 · 2416 阅读 · 0 评论 -
编程之美3.3——计算字符串的相似度
问题:1. 计算两个字符串的最长公共子序列(LCS),且公共子序列在字符串中不需要是连续的。2. 计算两个字符串的距离,完全相同的字符串距离为0,可以通过修改一个字符、增加一个字符或删除一个字符三种方式来使两个字符串相同,但这些方式会使得距离加1。1.解法:这两个问题的解法基本相同,都是二维的动态规划,都考虑字符串的后缀(实际上用动态规划更喜欢考虑前缀,但使用前缀时数组最好原创 2012-07-14 22:58:26 · 3172 阅读 · 1 评论 -
编程之美3.6——编程判断两个链表是否相交
问题:给出两个单向链表的头指针,而两个链表都可能带环,判断这两个链表是否相交,并且给出他们相交的第一个节点。解法:参考http://blog.csdn.net/ldong2007/article/details/4544203(1)判断链表是否存在环设置两个链表指针(fast, slow),初始值都指向链表头结点,然后连个指针都往前走,不同的是slow每次前进一步,fast原创 2012-07-17 00:46:26 · 12525 阅读 · 5 评论 -
求正数数组的子数组之和等于给定值
问题:1. 给定一个数组其每个元素都是正数,和一个给定值M,求所有连续的子数组其和等于M。2. 给定一个正数N,求所有和为N的连续正数序列。这类求子数组之和的问题与编程之美2.12——快速寻找满足条件的两个数或三个数问题的求解思路相似,都是可用双指针法在O(n)的时间内解决。1.解法:我们让两个指针i,j都从数组的第一个元素开始,记变量sum初始化为第一个元素的值,原创 2012-08-04 00:01:44 · 6028 阅读 · 4 评论 -
编程之美3.7——队列中取最大值操作问题
问题:假设有这样一个拥有3个操作的队列:1. EnQueue(v): 将v加入队列中2. DeQueue(): 使队列中的队首元素删除并返回此元素3. MaxElement: 返回队列中的最大元素设计一种数据结构和算法,让MaxElement操作的时间复杂度尽可能地低。解法1:用最大堆来维护队列中的节点,队列用单链表表示,每个节点包含数据,而最大堆用数组表示,数原创 2012-07-19 23:39:45 · 4942 阅读 · 5 评论 -
最小生成树Prim算法和单源最短路径Dijkstra算法
问题:1. (最小生成树)给定一个带权的无向连通图,如何选取一棵生成树,使树上所有边上权的总和为最小,即求最小生成树。2. (单源最短路径)给定一个权值都为正数的无向连通图和一个源点,确定它到其它点的最短距离。之所以将这两个问题放在一起,是因为Prim算法与Dijkstra算法的思路和程序都非常相似,都是有贪心策略。1.解法(Prim算法):思路:设连通网络 N原创 2012-07-28 14:51:46 · 6736 阅读 · 2 评论 -
编程之美2.5——寻找最大的K个数
问题:从一组数中选出其中最大的K个数,当这组数的个数为几百、几百万、几百亿时分别适合采用哪些算法? 个数为几百时,使用顺序统计法(看算法导论第9章): 算法思想是对输入数组进行递归划分,一边的数据小于选定数,另一边的数据大于等于选定数。但和快速排序不同的是,快速排序会递归处理划分的两边,而顺序统计法只处理划分的一边。其随机化算法的期望时间为O(n)。除了无法处理大规模的数据原创 2012-06-27 22:16:47 · 1647 阅读 · 0 评论 -
编程之美2.9——斐波那契数列
问题:斐波那契数列由如下递推关系式定义:F(0) = 0,F(1)=1,F(n)=F(n-1)+F(n-2) if n>1。解法:斐波那契数列是二阶递推数列,所以存在一个2*2的矩阵A,使得:(Fn, Fn-1) = (Fn-1, Fn-2)*A求得A=(1 1) (1 0)那么求数列的第n项就是等于求矩阵A的第n-1次幂,计算的速原创 2012-07-01 18:38:26 · 5178 阅读 · 0 评论 -
编程之美2.16——求数组中最长递增子序列
问题:求一个一维数组中最长递增子序列的长度。解法1:很明显用动态规划的算法,选取下面的阶段(这种选法极为常见),可使阶段间的关系具有无后效性。阶段:在所有以元素k结尾的子数组中,选出其中的最长递增子序列,k=1,2...n。状态:以元素k结尾的最长递增子序列中只有一个最长的递增子序列。决策:决定元素k结尾的最长递增子序列有k-1种获取的途径,前面以任何一个元素结原创 2012-07-08 22:05:29 · 3554 阅读 · 0 评论 -
编程之美2.15——二维子数组之和的最大值
问题:1. 求二维数组(矩阵)的子矩阵之和的最大值。2. 求三维数组(长方体)的子方体之和的最大值。解法:先计算出以左上角的元素(1,1)和当前元素(i,j)为顶点对的子矩阵的部分和,部分和的计算如下PS[i][j] = A[i][j]+PS[i-1][j]+PS[i][j-1]-PS[i-1][j-1]在上一篇文章中我们发现一维的解答可以线性完成,这里我们把问题从原创 2012-07-07 00:29:49 · 5769 阅读 · 0 评论 -
编程之美1.12——“拈”游戏分析
问题:有N块石头和两个玩家A和B,玩家A先将石头随机分成若干堆,然后按照BABA...的顺序不断轮流取石头,能将剩下的石头一次取光的玩家获胜,每次取石头时,每个玩家只能从若干堆石头中任选一堆,取这一堆石头中任意数目(大于0)个石头。请问:玩家A要怎样分配和取石头才能保证自己有把握取胜?如果石头的个数N为偶数,A只要将其分为相同的两份,就一定能取胜。初始:XOR(M1,原创 2012-06-13 22:16:29 · 1827 阅读 · 0 评论 -
编程之美1.15——构造数独
问题:构造一个9*9的方格矩阵,玩家要在每个方格中,分别填上1至9的任意一个数字,让整个棋盘每一列、每一行以及每一个3*3的小矩阵中的数字都不重复。首先我们通过一个深度优先搜索来生成一个可行解,然后随机删除一定数量的数字,以生成一个数独。#include #include using namespace std;#define LEN 9#define CLE原创 2012-06-18 17:18:16 · 3333 阅读 · 0 评论 -
编程之美1.13——NIM(3)两堆石头的游戏
问题: 假设有两堆石头,有两个玩家会根据如下的规则轮流取石头:每人每次可以从两堆石头中各取出数量相等的石头,或者仅从一堆石头中取出任意数量的石头;最后把剩下的石头一次拿光的人获胜。请问在哪些局面(依据两堆石头中的石头个数)下,先取石头的玩家有必胜的策略。解法: 类似构造质数的筛选方法,这里我们利用找到的必输局面(后取的玩家有必胜策略)来筛去原创 2012-06-18 21:11:14 · 3488 阅读 · 0 评论 -
编程之美1.16——24点游戏
问题:给玩家4张牌,每张牌的面值在1-13之间,允许其中有数值相同的牌,采用加、减、乘、除四则运算,允许中间运算存在小数,并且可以使用括号,但每张牌只能用一次。构造表达式,使其结果为24.解法:传统的枚举解法会产生大量重复的运算,主要有两类重复:运算结果的重复和排列的重复。假设4张牌为3 3 8 8,我们对3 3进行一次操作(6种运算)得到6 0 0 1 1 9,其中重复的数据就是原创 2012-06-20 19:55:37 · 2835 阅读 · 1 评论 -
编程之美2.11——寻找最近点对(POJ 3714)
问题:给定平面上N个点的坐标,找出距离最近的两个点。解法:我们先对N个点的x坐标进行排序,排序我们使用最坏复杂度O(n*logn)的快速排序方法,在排序的过程中minDifferent会递归计算出左右两边的最小距离,再用其中的较小值minum得到以中位数点附近的带状区域[p[median+1].x-median, p[median].x+median],对带状区域的点按照y坐标原创 2012-07-05 00:13:29 · 5171 阅读 · 3 评论 -
编程之美2.13——子数组的最大乘积
问题:给定一个长度为N的整数数组,只允许用乘法,不能用除法,计算任意(N-1)个数的组合中乘积最大的一组。解法一:采用空间换时间的策略,用两个数组分别记录原整数数组前缀与后缀的叠乘积(前缀s[i]=),再以间隔1个数的方式将这两个数组乘起来就得到所有n-1个数的乘积数组(具体看代码)。#include #include using namespace std;#de原创 2012-07-06 15:25:12 · 2915 阅读 · 0 评论 -
编程之美2.8——找符合条件的整数
问题:任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0。解法:由于没有直接的数学方法能帮我们直接得到M的值,所以我们只能进行搜索。由于相对M,乘积N*M具有明显的特征,需要搜索的空间要小很多,所以我们对乘积N*M进行搜索。如果N*M的结果有K位,则要循环2^K次,我们发现K的结果能轻易超过40,所以这个运行时间还是相当长。同余运原创 2012-07-01 00:40:56 · 3856 阅读 · 0 评论 -
编程之美2.1——求二进制树中1的个数
问题:对一个4字节的无符号整形变量,求其二进制表示中“1”的个数,要求算法的执行效率尽可能高。 解法一(位遍历法):使用位操作,移位后来判断是否有1存在,利用v&0x01和v>>=1。 解法二(1遍历法):在每次判断中只与1的个数进行判断,利用v&=v-1。 解法三(二分累加法):依次连续两位相加,连续四位相加,连续八位相加。以上操作得到4个八位数,每个八位数的值表示8原创 2012-06-24 19:25:11 · 2079 阅读 · 0 评论 -
编程之美1.17——俄罗斯方块游戏
问题:让电脑自动下俄罗斯方块游戏。解法:对当前的积木块,枚举它旋转后的每一个形状从每一列落下的棋盘,将该棋盘和前一个棋盘进行对比,并打分,最后取得分最高的那个形状和那一列作为电脑的当前操作。(由于程序的输入数据比较多,我将其和代码打包放在资源下载中,需要的读者可以去下载http://download.csdn.net/detail/linyunzju/4389102,鉴于有读者原创 2012-06-23 23:55:38 · 2483 阅读 · 2 评论 -
编程之美2.12——快速寻找满足条件的两个数或三个数
问题:1. 快速找出一个数组中的两个数,让这两个数之和等于一个给定的值。2. 快速找出一个数组中的三个数,让这三个数之和等于一个给定的值。1. 解法:算法复杂度为O(nlogn)。先用快速排序对数组排序,让后用双指针(双索引)法对排序好的数组进行反向遍历,并且遍历的方向不变。(若是计算两个数的和,则初始化为i=0,j=n-1,若是计算两个数的差,则初始化为i=0,j=1)之原创 2012-07-05 23:53:35 · 5091 阅读 · 0 评论 -
编程之美2.14——求数组的子数组之和的最大值
问题:1. 一个由N个整数元素的一维数组,求其所有子数组中元素和的最大值。2. 如果数组首尾相邻,也就是允许子数组A[i],...,A[n-1],A[0],...,A[j]存在,求其所有子数组总元素和的最大值。1. 解法:我们使用动态规划的思想可以在O(n)的时间内计算出子数组之和最大值。动态规划问题往往非常灵活,所以在做题的时候不知道如何编写,其实它有很清晰的分析方法原创 2012-07-06 22:21:11 · 2330 阅读 · 4 评论 -
编程之美2.18——数组分割
问题:1. 有一个无序、元素个数为2n的正整数数组,要求:如何能把这个数组分割为两个子数组,子数组的元素个数不限,并使两个子数组之和最接近。2. 有一个无序、元素个数为2n的正整数数组,要求:如何能把这个数组分割为元素个数为n的两个数组,并使两个子数组之和最接近。1. 解法1:由于对两个子数组和最接近的判断不太直观,我们需要对题目进行适当转化。我们知道当一个子数组之和最接近原创 2012-07-10 00:20:46 · 12360 阅读 · 8 评论