
算法
文章平均质量分 60
Leon__CAI
这个作者很懒,什么都没留下…
展开
-
寻找数组中前K个最小的数(Kth smallest element)---(堆排序的应用)
日常生活中我们总是遇到求解一个数组的最小值或者最大值等问题,这些问题基本上都可以在原创 2014-11-07 14:48:38 · 2516 阅读 · 0 评论 -
算法----堆排序(heap sort)
堆排序是利用堆进行排序的高效算法,其能实现O(NlogN)的排序时间复杂度,具体算法分析可以点击堆排序算法时间复杂度分析。算法实现:调整堆:void sort::sink(int* a, const int root, const int end){ int i=root; while(2*i +1 <= end) { int k = 2*i+1; if(k+1<=e原创 2014-11-16 21:44:46 · 1276 阅读 · 1 评论 -
算法---快速排序(quick sort)
在前面介绍的排序算法中,最快的排序算法为归并排序,但是归并排序有一个缺陷就是排序过程中需要O(N)的额外空间。本文介绍的快速排序算法时一种原地排序算法,所需的额外空间复杂度为O(1)。算法介绍:快速排序其实一种根据需找某个元素的具体位置进行排序的方法。比如所存在如下数组 选择第一个元素5,找到5最终的位置,即5的左边的数都小于或者等于5,右边的数都大于或者等于5.从"6"开原创 2014-11-16 21:40:52 · 1882 阅读 · 0 评论 -
排序算法总结
目前比较成熟的排序算法有选择排序,插入排序,希尔排序,归并排序,快速排序以及堆排序。如下表所示,比较了各个排序算法之间的优劣势。上述算法的具体实现选择排序:选择排序具体实现与分析插入排序:插入排序具体实现与分析希尔排序:希尔排序具体实现与分析归并排序:归并排序具体实现与分析快速排序:快速排序具体实现与分析堆排序:堆排序具体实现与分析原创 2014-11-16 22:01:06 · 808 阅读 · 0 评论 -
大-小顶混合堆的实现与应用(a min-max heap)
一般情况下我们使用的堆都是大顶堆或者小顶堆,其能实现在常数时间内获得数组的最大值或者最小值,同时满足在对数时间内删除和插入元素。但是如果要同时实现即能在常数时间内获得最大值和最小值,又能在对数时间内删除和插入元素,通常情况下的堆就不能满足上述要求了。为此介绍一种新的数据结构min-max heapmin-max heap 是一颗完全二叉树,但是二叉树的奇数层存的是max元素,偶数层存的是min原创 2014-11-18 17:49:19 · 2429 阅读 · 1 评论 -
二叉树转换为双向环形链表
二叉树的节点与双向环形链表的节点类似,均含有两个指向不同方向的指针,因此他们之间的转化是可以实现的。下面介绍一种递归的实现方法。由于方法比较简单,就直接上代码了二叉树的建立node* create(const string& s){ node* res = new node; res->left = nullptr; res->right = nullptr; res->s =原创 2014-11-25 15:15:35 · 1168 阅读 · 0 评论 -
中序遍历-----二叉查找树的遍历(迭代版,不使用栈或者队列)
二叉查找树(Binary Search Tree)的遍历的方法有很多,通常使用的是递归的遍历,其便于理解,但是使用递归的话会造成程序运行的空间浪费,效率并不高。为此可以使用一个栈来模拟递归的过程,实现迭代版的二叉查找树的遍历。但是会使用到额外的存储空间,虽说在运行效率上比递归版的有所提高,但是额外的存储空间还是一定的浪费。但是如何减少额外的存储空间呢?我们知道二叉查找树是可以转换为一个双向环形链表原创 2014-11-25 11:09:41 · 1688 阅读 · 0 评论 -
优惠劵收集问题
假设有N张不同的优惠劵,请问你需要收集此优惠劵原创 2014-11-06 21:28:04 · 2136 阅读 · 0 评论 -
多数投票算法(Majority Vote Algorithm)
假设有一个字符串数组,其中含有N个元素,qi原创 2014-11-06 23:29:47 · 9904 阅读 · 1 评论 -
欧拉回路(Euler Circuit)
定义:若一副图中从某个顶点A走出,经过图中的所有的边,且每条边只经过一次,则称这个环为欧拉回路,如果某幅图含有这样的环,则这幅图叫做欧拉图。如何判断一幅图是不是欧拉图,也即一幅图中是否含有欧拉回路。如果一幅图中所有顶点的出度等于入度,且此图为强连通图,则此图含有欧拉回路,这幅图为欧拉图。如何在程序中实现判断一副图是否含有欧拉回路呢?如果存在,则将路径打印出来。判断是否为原创 2014-12-09 23:15:10 · 6318 阅读 · 0 评论 -
让我们来谈谈最小生成树(Minimum Spanning Tree)算法
现实生活中我们往往会遇到类似于旅游路线规划,使用怎么样的一条旅游路线能够让我们花费最少的旅费获得一样的感受。这时如果你学过算法的话,恭喜你可以在女票面前大显生手了。这其实是一个最小生成树问题,可以利用Prim算法或者Kruskal算法解决。下面一一介绍这两种算法。Prim算法包括两种不同的实现方式,其中一种叫做延时Prim算法,一种叫做即使Prim算法,两种算法的基本原理相同,只是实现过程中存原创 2014-12-24 21:34:25 · 3755 阅读 · 1 评论 -
算法---归并排序(Merge Sort)---多版本对比
归并排序是一种利用“分治”手段来实现的排序方法,其通过二分将数组分为若干个有序的子数组,然后再将这些子数组合并到一起组成一个新的数组。算法的具体实现:void sort::merge_sort(int* a, const int low, const int high){ if(low>= high) return; int mid = (low+high)/2; merge_原创 2014-11-13 22:58:14 · 1769 阅读 · 0 评论 -
算法----希尔排序(shell sort)
在分析插入排序的算法性能的过程时知道,当数组规模较小或者存在较多的有序子序列时,插入排序将会在很短的时间内完成数组的排序,为此可以设计一个单调序列h[n],将数组分为多个小的序列,然后这些小的序列使用插入排序。h[n]={1,4,7,10,13,16,19……,3*x+1}。算法实现:void sort::shell_sort(int* a, const int n){ int h =原创 2014-11-12 22:54:46 · 1357 阅读 · 0 评论 -
算法----选择排序(select sort)
选择排序就是每次将未排序的数组中最小的一个元素找出,将其与数组的第一个元素交换,从而完成数组的排序。算法实现:void sort::select_sort(int* a,const int n){ for(int i=0 ;i<n; i++) { int min = i; for(int j=i+1; j<n; j++) { if(a[j] < a[min])原创 2014-11-12 22:40:03 · 1557 阅读 · 0 评论 -
关于查找数组中是否存在重复元素的方法总结(Find A Duplicate)
检验数组中是否存在重复元素是一个简单的办法,能够在O(1)的额外空间复杂度下实现线性时间复杂度的查找方法,希望对您的算法学习有所帮助原创 2014-11-07 17:52:57 · 13811 阅读 · 3 评论 -
排序旋转数组查找(Search in a sorted, rotated list)
假设存在一个按升序排列的数组A,让A绕其中的一个元素旋转180度得到新的数组A1,如何在对数时间复杂度内完成对A1的查找呢?对于A1这样的数组,我们仍可使用二分查找来找寻其中的元素,只是,在二分查找之前,需要找到其分界点,这样分界点的两边分别为增序数组,从而可以使用二分查找。因此上述问题的主要操作就是在找寻这个分界点。原创 2014-11-08 11:05:25 · 795 阅读 · 0 评论 -
找出矩阵中含有0最多的一行(find the longest row of zero)
对于一个n*n的矩阵,其中只包含有0,1两种元素且,所有的0都在1之前,请找出矩阵中0最多的一行。(Given an N-by-N matrix of 0s and 1s such that in each row no 0 comes before a 1, find the row with the most 0s in O(N) time.)初看这题,想到的算法就是每一行都设置一个计原创 2014-11-10 19:53:43 · 2721 阅读 · 0 评论 -
双调数组查找(Bitonic search)
数组查找是一个非常常见的问题,u原创 2014-11-04 16:04:50 · 2897 阅读 · 9 评论 -
扔鸡蛋问题(eggs drop)
前两天看书的时候看到这样一个问题,十分有趣,再次分享给大家。jia原创 2014-11-05 14:43:43 · 2723 阅读 · 2 评论 -
剖析3-sum问题(Three sum)
日常生活中经常遇到求解数组中是否存在和为0的三个数,即3-sum问题,为此本文介绍一些比较实用的方法,并在暴力计算的基础上对算法逐步改进,以达到最优的算法。首先介绍一下2-sum问题,3-sum问题其实就是2-sum问题的一个扩展而已。对于2-sum问题,最一般的想法就是使用两层循环直接枚举数组中的所有元素对,直到找到和为0的元素对为止。int sum_2(){ int res原创 2014-11-03 23:38:33 · 6638 阅读 · 4 评论 -
栈与队列(queue and stack)
题目:使用有限个栈实现队列,保证每个队列操作都只需要常数此栈的操作初看题目感觉似乎单个栈可以在常数次栈操作的情况下实现出队列或者入队列的操作,但是考虑到可以使用多个栈,则可以优化相应的出入队列时间。为此选择两个栈来实现队列。其中一个栈实现入队列操作,另一个栈负责出队列操作,入队列只需要使用栈的push操作即可,但出队列则需要进行一次“倒入”操作,将控制入队列的栈中的元素“倒入”出队列中。如原创 2014-11-02 16:33:48 · 1361 阅读 · 0 评论 -
寻找数组中缺少的整数(Find the missing integer)
数组a中含有N个元素,其元素属于[0,N]之间,且不存在重复的元素,请你找出数组中缺失的元素(因为[0,N]之间有N+1个元素,而数组只能存储N个元素,所以必然缺少一个元素)。其中对数组的操作满足下列的条件:不能在常数时间内读取数组中的元素,但是可以读取数组中元素的某一个bit值,能够在常数时间内交换数组的两个元素的位置。请设计一种算法使其能够在线性时间内找出数组中缺失的元素。(N=2^k)A原创 2014-11-08 14:26:28 · 2229 阅读 · 1 评论 -
比较二分查找与斐波那契查找(binary search & fibonacci search)
数组查找时一个很常见的问题,通产的查找方式一般为二分查找,youshi原创 2014-11-04 20:04:35 · 3025 阅读 · 8 评论 -
算法----插入排序(insert sort)
插入排序就是每次选取一个元素插入到已经排序的子数组中,如此循环,直到所有的元素都完成排序。算法实现:void sort::insert_sort(int* a, const int n){ for(int i=1; i<n; i++) { for(int j=i; j>0 && a[j] < a[j-1]; j--) { swap(a,j,j-1); } }}原创 2014-11-12 22:40:59 · 3300 阅读 · 0 评论 -
双调旅行商问题 (Bitonic TSP)
问题描述:上述问题可以使用动态规划的方法来解决。下面是解决思路的具体介绍:1. 最优子结构:假设d[i][j]表示从起点1出发到达i及j两个顶点的最短路程之和。为此可以假设K为此段路程上与j相加的节点,则d[i][j] = d[i][k] + len[k][j]。证明:若存在一个更短的路径d[i][k],则就应该存在更短的路径d[i][j],这与假设矛盾,因此得证。下面来寻找j相原创 2015-07-06 11:01:08 · 3383 阅读 · 0 评论