
算法系列
文章平均质量分 56
爱橙子的OK绷
时刻准备着。。。
展开
-
最长公共子序列(LCS)
LCS的定义最长公共子序列,即Longest Common Subsequence,LCS。一个序列S任意删除若干个字符得到新序列T,则T叫做S的子序列两个序列X和Y的公共子序列中,长度最长的那个,定义为X和Y的最长公共子序列。 -字符串13455与245576的最长公共子序列为455 -字符串acdfg与adfc的最长公共子序列为adf注意区别最长公共子串(Longest Common原创 2015-05-03 15:07:01 · 824 阅读 · 0 评论 -
九大排序算法总结
转自http://blog.youkuaiyun.com/xiazdong/article/details/8462393stable sort:插入排序、冒泡排序、归并排序、计数排序、基数排序、桶排序。 unstable sort:选择排序、快速排序、堆排序。一、插入排序特点:stable sort、In-place sort 最优复杂度:当输入数组就是排好序的时候,复杂度为O(n),而快速排序在这种情况转载 2015-06-15 15:01:23 · 1110 阅读 · 0 评论 -
回溯法与分支限界法
回溯法1、概念回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。许多复杂的,规模较大的问题都可以使用回溯法,有转载 2016-03-24 15:20:04 · 2077 阅读 · 0 评论 -
给定一个仅包含'A'-'Z'的字符串,表示成'kX'形式输出
问题描述:给定一个仅包含’A’-’Z’的字符串,用下面的方法进行编码: (1)每个包含k个相同字符的子串要表示成”kX”,其中X是由唯一字符组成的子串。(2)如果某个子串的长度为1,则1忽略不写。 输入:第1行输入一个整数N(1<=N<=100) ,代表要处理的字符串的个数。接下来的N行就分别输入一个只包含’A’-’Z’的字符串,每个字符串的长度小于10000. 输出:对于每个字符串,在单独的原创 2016-03-23 20:19:16 · 4316 阅读 · 0 评论 -
编程之美---寻找发帖“水王”
问题描述:Tango是微软亚洲研究院的一个试验项目。研究院的员工和实习生们都很喜欢在Tango上面交流灌水。传说,Tango有一大“水王”,他不但喜欢发贴,还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子总数的一半。如果你有一个当前论坛上所有帖子(包括回帖)的列表,其中帖子作者的ID也在表中,你能快速找出这个传说中的Tango水王吗? 转化:数组中有一个数字出现的次数超过了数组长原创 2015-05-26 10:56:33 · 899 阅读 · 0 评论 -
Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间)
本文主要解决一个问题,如何按下述两个要求实现二叉树的前中后序遍历:1、 O(1)空间复杂度,即只能使用常数空间;2、 二叉树的形状不能被破坏(中间过程允许改变其形状)。通常,实现二叉树的前序(preorder)、中序(inorder)、后序(postorder)遍历有两个常用的方法:一是递归(recursive),二是使用栈实现的迭代版本(stack+iterative)。这两种方法都是O(n)的转载 2015-12-31 16:40:45 · 415 阅读 · 1 评论 -
Floyd-Warshall算法---求解任意两节点的最短路径
算法描述:简称Floyd算法,是一种基于DP(Dynamic Programming)的最短路径算法,时间复杂度是O(V^3)。 精简版一般形式:void Floyd(){ int i,j,k; for(k=1;k<=n;k++) for(i=1;i<=n;i++) for(j=1;j<=n;j++)原创 2015-06-14 16:12:37 · 1032 阅读 · 0 评论 -
差分约束系统---算法导论第24章
差分约束系统:以算法导论中的问题为例:X1 - X2 <= 0X1 - X5 <= -1X2 - X5 <= 1X3 - X1 <= 5 (1)X4 - X1 <= 4X4 - X3 <= -1X5 - X3 <= -3X5 - X4 <= -3这样的不等式组就称作差分约束系统。注意: x1-x2<=w在图上对应的是x2->x1的边权为w的一条边,而不是x1->x原创 2015-06-12 18:02:31 · 949 阅读 · 0 评论 -
排序查找算法实战---Median of Two Sorted Arrays
题目描述:求两个有序数组的中位数(Leetcode 4)题目求解:求解核心思想:转化为求第k小元素方法一:归并排序归并到第k个为止时间复杂度O(k)该方法在Leetcode上会由于超时而 Runtime Error,但思想可以借鉴实现代码(c++):class Solution {public: int findKth(vector<int> a, vector<int> b,原创 2015-05-07 17:20:09 · 516 阅读 · 0 评论 -
排序算法-冒泡排序的三种实现
1、最基本版本冒泡排序是非常容易理解和实现,设数组长度为N,以从小到大排序举例:1)比较相邻的前后2个数据,如果前面数据大于后面的数据,就将2个数据交换。 2)这样对数组的第0个数据到N-1个数据进行一次遍历后,最大的一个数据就“沉”到数组第N-1个位置(也可以是把最小的元素浮到最前面)。 3)N=N-1,如果N不为0就重复前面2步,否则排序完成。代码见://冒泡排序版本12、改进版本一下面对其转载 2016-04-13 09:44:04 · 411 阅读 · 0 评论 -
算法系列-直接插入排序和希尔排序
直接插入排序(Insertion Sort)的基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止。设数组为a[0…n-1]。 1)初始时,a[0]自成1个有序区,无序区为a[1..n-1]。令j=1 2)将a[j]并入当前的有序区a[0…j-1]中形成a[0…j]的有序区间。 3)j++并重复第二步直到j==n-1。排序完成。代原创 2016-04-13 13:26:27 · 468 阅读 · 0 评论 -
二分查找-有重复数和无重复数
1、适用于无重复数的版本二分查找要求数组有序,时间复杂度为O(lgn)。适用于无重复数的版本如下:#include<iostream>using namespace std;int biSearch(int a[], int n, int key){//非递归 int low=0, high=n-1, mid; while(low<=high) { mid原创 2016-05-24 14:27:31 · 3153 阅读 · 0 评论 -
排序算法杂记
1、精简排序,即一对数字不进行两次和两次以上的比较,以下是“精简排序”的是正确答案: A B A、插入排序 B、归并排序 C、选择排序 D、堆排序插入排序:前面是有序的,后面的每一个元素与前面有序的元素比较,比较过的就是有序的了,不会再比较一次,例如:3 2 1 5 第一趟:【2,3,1,5】,2和3比较,3后移;第二趟:【1,2,3,5】,1和2,1和3比较,而2,原创 2016-04-03 16:43:11 · 1250 阅读 · 0 评论 -
如何赢得数学游戏(博弈问题)
数学游戏(博弈问题)是最优化问题中的一类,同时它也是一类很有趣的逻辑推理问题。其中运用最广的思维是:倒推思维。例1.桌子上有24根火柴,甲、乙两人轮流取,每人每次取1—3根。谁取到最后一根谁就获胜。甲该怎样取才能保证获胜?解析:甲要获胜,就要拿到第24根火柴;要想拿到第24根火柴,必须先拿到第20根;要想拿到第20根,必须先拿到第16根,同理可推出,甲必须先拿到第12、8、4根,甲才获胜。所以,解决转载 2016-04-24 11:39:36 · 3110 阅读 · 0 评论 -
自平衡二叉搜索树:红黑树 VS AVL树
红黑树(RBT)AVL是严格平衡树,因此在增加或者删除节点的时候,根据不同情况,旋转的次数比红黑树要多; 红黑树是弱平衡的,用非严格的平衡来换取增删节点时候旋转次数的降低;红黑树上每个结点内含五个域,color,key,left,right,p。如果相应的指针域没有,则设为NIL。 一般的,红黑树,满足以下性质,即只有满足以下全部性质的树,我们才称之为红黑树:1)每个结点要么是红的,要么是黑的。转载 2016-04-05 23:05:21 · 1100 阅读 · 0 评论 -
Top K算法
1、查找最大的k个元素1、排序,快速排序。我们知道,快速排序平均所费时间为n*logn,从小到大排序这n个数,然后再遍历序列中后k个元素输出,即可,总的时间复杂度为O(n*logn+k)=O(n*logn)。2、排序,选择排序。用选择或交换排序,即遍历n个数,先把最先遍历到得k个数存入大小为k的数组之中,对这k个数,利用选择或交换排序,找到k个数中的最小数kmin(kmin设为k个元素的数组中最小元转载 2016-04-11 13:15:49 · 625 阅读 · 0 评论 -
算法系列-快速排序
快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。该方法的基本思想是: 1)先从数列中取出一个数作为基准数。 2)分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。 3)再对左右区间重复第二步,直到各区间只有一个数。虽然快速排序称为分治法,但分治法这三个字显然转载 2016-04-14 10:58:05 · 465 阅读 · 0 评论 -
算法系列-归并排序
时间复杂度:O(nlogn). 空间复杂度:O(n).基本思路:将数组分成2组A,B,如果这2组组内的数据都是有序的,那么就可以很方便的将这2组数据进行排序。如何让这2组组内数据有序?可以将A,B组各自再分成2组。依次类推,当分出来的小组只有1个数据时,可以认为这个小组组内已经达到了有序,然后再合并相邻的2个小组。这样通过先递归的分解数列,再合并数列就完成了归并排序。#include <iostr原创 2016-04-13 23:53:20 · 304 阅读 · 0 评论 -
算法系列-直接选择排序
直接选择排序和直接插入排序类似,都将数据分为有序区和无序区,所不同的是直接插入排序是将无序区的第一个元素直接插入到有序区以形成一个更大的有序区,而直接选择排序是从无序区选一个最小的元素直接放到有序区的最后,也就是无序区开头的位置。设数组为a[0…n-1]。 1)初始时,数组全为无序区为a[0..n-1]。令i=0 2)在无序区a[i…n-1]中选取一个最小的元素,将其与a[i]交换。交换之后a[原创 2016-04-13 16:35:37 · 371 阅读 · 0 评论 -
编程之美---发帖“水王”扩展问题
扩展问题一:随着Tango的发展,管理员发现,“超级水王”没有了。统计结果表明,有3个发帖很多的ID,他们的发帖数目都超过了帖子总数目N的1/4。你能从发帖ID列表中快速找出他们的ID吗?问题求解:上题只需要一个结果,而现在需要3个结果,所以我们考虑数组作为返回值,同时,上题用到的nTimes,也应改为一个大小为3的数组。我们要如何保证最终返回的数组的3个元素就是3个灌水最多的用户呢?首先分析其所占原创 2015-05-26 14:54:54 · 1504 阅读 · 0 评论 -
编程之美---求二进制数中1的个数
问题描述:对于一个字节(8bit)的无符号整型变量,求其二进制表示中”1”的个数,要求算法的执行效率尽可能的高。问题求解:#include <iostream>using namespace std;#define BYTE unsigned char/*解法1:利用整型数据除法特点,通过相除和判断余数的值来分析.每次除二,看是否为奇数,是的话就累计加一,最后这个结果就是二进制表示中1的个数原创 2015-05-25 14:46:43 · 575 阅读 · 0 评论 -
并查集---判断图中是否存在环
算法描述:并查集(union-find sets)是一种简单的用途广泛的集合. 并查集是若干个不相交集合,能够实现较快的合并和判断元素所在集合的操作,应用很多,如其求无向图的连通分量个数、最小公共祖先、带限制的作业排序,还有最完美的应用:实现Kruskar算法求最小生成树。算法实现://并查集判断是否存在环#include <iostream>#include <stdlib.h>#inclu原创 2015-06-02 21:23:25 · 3187 阅读 · 1 评论 -
算法导论---有序序列中的i个最大数(思考题9-1)
问题描述:问题求解:a. 使用归并排序或堆排序对输入数据进行排序,均花费O(n*lgn)最坏情况运行时间(不要使用快排或插入排序,他们均花费O(n^2)的时间)。将i个最大元素(在已排序数组中直接可以获得)放到输出数组中,花费时间O(i)。 因此,总的最坏情况运行时间:O(n * lgn+i)=O(n * lgn) (因为i <= n)。b.用堆来实现优先队列。使用BUILD-HEAP建堆,花原创 2015-06-21 09:55:23 · 982 阅读 · 0 评论 -
算法导论第三章--- 渐进记号
|概念回顾|几个重要渐进记号的定义:Θ(g(n))={ f(n): 存在正常数c1,c2和n0,使对所有的n>=n0,有0<=c1g(n)<=f(n)<=c2g(n) }O(g(n))={ f(n): 存在正常数c和n0,使对所有n>=n0,有0<=f(n)<=cg(n) }Ω(g(n))={ f(n): 存在正常数c和n0,使对所有n>=n0,有0<=cg(n)<=f(n) }o(g(n))转载 2015-06-16 16:34:14 · 2704 阅读 · 0 评论 -
算法导论习题---求n个元素任何排列中逆序对的数量
问题描述:设A[1…n]是一个包含n个不同数的数组。如果在i < j的情况下,有A[i] > A[j],则(i,j)就称为A中的一个逆序对(inversion),(逆序对的元素是下标,而不是数组里的值)。给出一个算法,它能用Θ(nlgn)的最坏情况运行时间,确定n个元素的任何排列中逆序对的数目。问题求解:方法一: 循环从数组中取出一个元素k,然后从k之后的元素中找到比k小的元素个数,最后统计所有的原创 2015-06-16 15:20:06 · 9714 阅读 · 2 评论 -
查找排序实战---荷兰国旗问题(leetcode 75)
问题描述:leetcode 75 荷兰国旗问题 有一个数组,存储着三种颜色值红、白、蓝,排序来使得相同的颜色都靠在一起,按红、白、蓝的颜色排序。 为了方便,这里使用0、1、2分别代表红、白。蓝。问题求解:解法1:通过交换,对0,1,2进行排序 复杂度O(n)class Solution {public: void sortColors(vector<int>& nums) {原创 2015-05-28 10:29:19 · 1591 阅读 · 0 评论 -
编程之美---求1的数目
问题描述:给定一个十进制正整数N,写下从1开始,到N的所有整数,然后数一下其中出现的所有“1”的个数。 例如: N=2,写下 1,2。这样只出现了 1 个“1”。 N=12,我们会写下 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12。这样 1 的个数是 5。 问题是: 1. 写一个函数f(N),返回1到N之间出现的“1”的个数,比如f(12)=5。 2. 在3原创 2015-05-27 14:31:12 · 509 阅读 · 0 评论 -
编程之美---求数组的子数组之和的最大值
问题描述:一个有N个整数元素的一维数组(A[0],A[1],A[2],...A[n-1]),这个数组中子数组之和的最大值是多少?该子数组是连续的。例如 数组:[1,-2,3,5,-3,2]返回8; 数组:[0,-2,3,5,-1,2]返回9问题求解:#include <iostream>#include <malloc.h>#include <limits.h>using namespace原创 2015-05-13 22:16:31 · 503 阅读 · 0 评论 -
编程之美---求首尾相连数组子数组之和的最大值
问题描述: 如果数组首尾相连,即允许找到一组数字(A[i],···,A[n-1], A[0],···, A[j]),请使其和最大,怎么办? 问题求解: 问题的解可以分为两种情况: 1)解没有跨过A[n-1]到A[0],即普通的求子数组和的最大值 2)解跨过A[n-1]到A[0] 对第二种情况,只要找到从A[0]开始和最大的一段(A[0],…,A[j])(0<=j < n)以及A[n-转载 2015-05-15 21:07:13 · 756 阅读 · 0 评论 -
Prim---求最小生成树(贪心算法)
算法步骤:假设N=(V,{E})是连通图,TE是N上最小生成树中边的集合。算法从U={u0}(u0∈V),TE={}开始,重复执行下述操作:在所有u∈U,v∈V-U的边(u,v)∈E中找一条代价最小的边(u0,v0)并入集合TE,同时v0 并入U,直至U=V为止。此时TE中必有n-1条边,则T=(V,{TE})为N的最小生成树。具体步骤如下:1) 创建一个集合mstSet记录已经包含在MST中的顶点原创 2015-06-04 22:10:04 · 1377 阅读 · 0 评论 -
如何计算算法的时间复杂度
时间复杂度的定义 一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示, 若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零 的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n))为算法的渐进 时间复杂度(O是数量级的符号 ),简称时间复杂度。根据定义,可以归纳出基本的计算步骤 计算出基本操作转载 2015-05-25 09:25:18 · 1633 阅读 · 0 评论 -
编程之美---求N!的二进制表示中最低位1的位置
问题描述:求N!的二进制表示中最低位1的位置。例如:给定N=3,N!=6,那么N!的二进制表示(1010)的最低位1在第二位。问题求解: 这个问题等同于求N!含有质因数2的个数,因为二进制最低位为0代表是偶数,可以被2整除,如果为1则代表是奇数,不能被2整除,其内部也不会包含质因数2,所以质因数2的个数就是二进制表示中最低位1后面的0个数。所以,答案等于N!含有质因数2的个数加1 。N!中含有质因原创 2015-05-25 21:13:56 · 1629 阅读 · 1 评论 -
赫夫曼编码---Huffman code(贪心算法)
算法描述:赫夫曼编码是一种无损数据压缩算法。在计算机数据处理中,赫夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。例如,在英文中,e的出现机率最高,而z的出现概率则最低。当利用赫夫曼编码对一原创 2015-06-09 12:02:19 · 8260 阅读 · 0 评论 -
散列表---算法导论第十一章 Hash Tables
一、散列表概念1、 直接寻址表 直接将关键字作为数组下标。复杂度O(1)2、 散列表 k->h(k) 降低了空间开销,会产生碰撞,解决碰撞的简单方法是链接法。 对链接法散列,平均情况下,复杂度也是O(1)3、 散列函数 1) 除法散列法 h(k)=k mod m,m最好选取与2的整数幂不太接近的质数 2) 乘法散列法 h(k)=[m(kA mod 1)], A为一个原创 2015-06-07 15:32:08 · 935 阅读 · 1 评论 -
Dijkstra---求单源最短路径(贪心算法)
算法步骤:1) Create a set sptSet (shortest path tree set) that keeps track of vertices included in shortest path tree, i.e., whose minimum distance from source is calculated and finalized. Initially, th原创 2015-06-05 17:47:46 · 1647 阅读 · 0 评论 -
摊还分析---算法导论第十七章
摊还分析是用来评价程序中的一个操作序列的平均代价,有时可能某个操作的代价特别高,但总体上来看也并非那么糟糕,可以形象的理解为把高代价的操作“分摊”到其他操作上去了,要求的就是均匀分摊后的平均代价。摊还分析有三种常用的技术:聚合分析,核算法,势能法。首先看个例子,现在有三种操作,push(s),pop(s),mutlipop(s,k),push(s),统称为栈操作。 push(s)每次只能压一个数据,转载 2015-06-26 17:36:37 · 3681 阅读 · 0 评论 -
Bellman-Ford算法---求包含负权边单源最短路径(动态规划)
单源最短路径:给定一个图,和一个源顶点src,找到从src到其它所有所有顶点的最短路径,图中可能含有负权值的边。 Dijksra的算法是一个贪婪算法,时间复杂度是O(VLogV)(使用最小堆)。但是迪杰斯特拉算法在有负权值边的图中不适用, Bellman-Ford适合这样的图。在网络路由中,该算法会被用作距离向量路由算法。 Bellman-Ford也比迪杰斯特拉算法更简单和同时也适用于分布式系原创 2015-06-04 22:43:13 · 3923 阅读 · 0 评论 -
非递归中序遍历---算法导论12.1-3
问题描述:给出一个非递归的中序树遍历算法。(提示:有两种方法,在较容易的方法中,可以采用栈作为辅助数据结构;在较为复杂的方法中,不采用栈结构,但假设可以测试两个指针是否相等。)构造的树如下: 中序遍历结果为:1 2 3 4 5 6 7 8 9 算法实现://非递归用栈实现中序遍历void BinaryTree::non_recurse_using_stack_in_order_visit(Nod原创 2015-06-25 14:18:13 · 573 阅读 · 0 评论 -
Kruskal---求最小生成树(贪心算法)
算法描述:一个图的生成树是一个树并把图的所有顶点连接在一起。一个图可以有许多不同的生成树。最小生成树其实是最小权重生成树的简称。最小生成树有(V – 1)条边,其中V是给定的图的顶点数量。Kruskal算法是一种贪心算法。贪心的选择是选择最小的权重的边,并不会和当前的生成树形成环。算法步骤:1,按照所有边的权重排序(从小到大)2,选择最小的边。检查它是否形成与当前生成树形成环。如果没有形成环,将这条原创 2015-06-02 21:33:38 · 3373 阅读 · 0 评论 -
堆排序
#include<iostream>using namespace std;void maxHeapfy(int a[], int i, int heapsize){//大顶堆 int left=2*i+1, right=2*i+2; int largest=i; //注意都是和a[largest]比较!!! if(left<heapsize && a[left]原创 2016-08-31 15:58:58 · 678 阅读 · 0 评论