算法
文章平均质量分 89
@SmartSi
Stay Hungry, Stay Foolish
展开
-
[算法系列]算法一 地理空间距离计算优化
1. 地理空间距离计算面临的挑战打开美团app,不管是筛选团购还是筛选商家,默认的排序项都是“离我最近”或者“智能排序”(如下图所示):不管是“离我最近”还是“智能排序”,都涉及到计算用户位置与各个团购单子或者商家的距离(注:在智能排序中距离作为一个重要的参数参与排序打分)。以筛选商家为例,北京地区有5~6w个POI(本文将商家称之为POI),当用户进入商家页,请求北京全城+所有品类+离我最近/智转载 2017-11-15 09:52:55 · 2876 阅读 · 2 评论 -
[算法系列之二十九]Bellman-Ford最短路径算法
单源最短路径给定一个图,和一个源顶点src,找到从src到其它所有所有顶点的最短路径,图中可能含有负权值的边。Dijksra的算法是一个贪婪算法,时间复杂度是O(VLogV)(使用最小堆)。但是迪杰斯特拉算法在有负权值边的图中不适用,Bellman-Ford适合这样的图。在网络路由中,该算法会被用作距离向量路由算法。Bellman-Ford也比迪杰斯特拉算法更简单和同时也适用于分布式系统。但Bell转载 2015-04-23 15:15:27 · 6887 阅读 · 0 评论 -
[算法系列之二十九][背包问题]01背包
题目有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。基本思路这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。状态转移方程:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}这个方程非常重要转载 2015-03-31 11:31:14 · 1331 阅读 · 0 评论 -
[算法系列之二十七]Kruskal最小生成树算法
简介求最小生成树一共有两种算法,一个是就是本文所说的Kruskal算法,另一个就是Prime算法。在详细讲解Kruskal最小生成树算法之前,让我们先回顾一下什么是最小生成树。我们有一个带权值的图,我们要求找到一个所有生成树中具有最小权值的生成树。如下图所示,T是图G的生成树。但不是具有最小权值的生成树。我们可以把他们想象成一组岛屿和连接它们的可能的桥梁。当然修桥是非常昂贵和费时的,所以我们必须要知翻译 2015-03-14 17:33:28 · 2404 阅读 · 0 评论 -
[算法系列之十八]海量数据处理之BitMap
一:简介所谓的BitMap就是用一个bit位来标记某个元素对应的Value, 而Key即是该元素。由于采用了bit为单位来存储数据,因此在存储空间方面,可以大大节省。二:基本思想我们用一个具体的例子来讲解,假设我们要对0-7内的5个元素(4,7,2,5,3)排序(这里假设这些元素没有重复)。那么我们就可以采用BitMap的方法来达到排序的目的。要表示8个数,我们就只需要8个bit(1Bytes)。原创 2015-02-07 16:34:19 · 7211 阅读 · 1 评论 -
[算法系列之二十六]字符串匹配之KMP算法
一 简介KMP算法是一种改进的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J.H.Morris同时发现,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。二 基于部分匹配表的KMP算法举例来说,有一个字符串”BBC ABCDAB ABCDABCDABDE”,我想知道,里面是否包含搜索串原创 2015-03-01 19:14:41 · 1999 阅读 · 0 评论 -
[算法系列之二十三]线段树(Interval Tree)
一 背景在信息学竞赛中,我们经常会碰到一些跟区间有关的问题,比如给一些区 间线段求并区间的长度,或者并区间的个数等等。这些问题的描述都非常简单,但是通常情况下数据范围会非常大,而朴素方法的时间复杂度过高,导致不能在规定时间内得到问题的解。这时,我们需要一种高效的数据结构来处理这样的问题,在本文中,我们介绍一种基于分治思想的数据结构—-线段树。二 简介线段树是一种二叉树形结构,属于平衡树的一种。它将转载 2015-02-25 13:24:29 · 12955 阅读 · 1 评论 -
[算法系列之五]快速排序
【分析】【伪代码】【运行过程】【代码】/********************************** 日期:2014-04-01* 作者:SJF0115* 题目:快速排序**********************************/#include #include using namespace原创 2014-05-03 14:28:31 · 2067 阅读 · 0 评论 -
[算法系列之四]优先级队列
概念优先级队列,顾名思义,就是一种根据一定优先级存储和取出数据的队列。它可以说是队列和排序的完美结合体,不仅可以存储数据,还可以将这些数据按照我们设定的规则进行排序。优先级队列是堆的一种常见应用。有最大优先级队列(最大堆)和最小优先级队列(最小堆)。优先级队列是一种维护有一组元素构成的集合S的数据结构。优先队列支持的基本运算[cpp] view plai原创 2014-05-03 09:15:50 · 2160 阅读 · 0 评论 -
[算法系列之八]大数问题(高精度运算)
【大数相加】[cpp] view plaincopy#include #include char a[10001],b[10001],sum[10002]; int BigIntegerAdd(){ //两个数的长度 int lena = strlen(a); int原创 2015-01-28 10:09:51 · 3683 阅读 · 3 评论 -
[算法系列之三十]Dijkstra单源最短路径算法
单源最短路径问题给定一个带权有向图 G=(V,E) ,其中每条边的权是一个非负实数。另外,还给定 V 中的一个顶点,称为源。现在我们要计算从源到所有其他各顶点的最短路径长度。这里的长度是指路上各边权之和。这个问题通常称为单源最短路径问题。前面Bellman-Ford最短路径算法讲了单源最短路径的Bellman-Ford算法(动态规划算法)。这里介绍另外一个更常见的算法Dijkstra算法。Dijks转载 2015-04-23 17:30:47 · 3068 阅读 · 0 评论 -
[算法系列之二]二叉树各种遍历
树形结构是一类重要的非线性数据结构,其中以树和二叉树最为常用。二叉树是每个结点最多有两个子树的有序树。通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用作二叉查找树和二叉堆或是二叉排序树。二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2的 i -1次方个结点;原创 2014-04-29 22:02:51 · 7469 阅读 · 2 评论 -
[算法系列之十一]荷兰国旗问题
【问题】现有红白蓝三个不同颜色的小球,乱序排列在一起,请重新排列这些小球,使得红白蓝三色的同颜色的球在一起。这个问题之所以叫荷兰国旗问题,是因为我们可以将红白蓝三色小球想象成条状物,有序排列后正好组成荷兰国旗。【分析】这个问题我们可以将这个问题视为一个数组排序问题。红白蓝分别对应数字0、1、2。红、白、蓝三色小球数量并不一定相同。【思路一】First, iterate th原创 2015-02-04 18:17:56 · 8854 阅读 · 0 评论 -
算法精品文选
[算法系列之一]堆排序 (sjf0115)[算法系列之二]二叉树各种遍历 (sjf0115)[算法系列之三]二叉树中序前序序列(或后序)求解树 (sjf0115)[算法系列之四]优先级队列 (sjf0115)[算法系列之五]快速排序 (sjf0115)[算法系列之六]二叉查找树 (sjf0115)[算法系列之七]Manacher算法之最大回文子串 (sjf0115)[算原创 2016-01-04 20:57:37 · 2854 阅读 · 0 评论 -
[算法系列之三十一]最近公共祖先(LCA)
【简介】对于有根树T的两个结点u、v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u、v的祖先且x的深度尽可能大。另一种理解方式是把T理解为一个无向无环图,而LCA(T,u,v)即u到v的最短路上深度最小的点。例如,对于下面的树,结点4和结点6的最近公共祖先LCA(T,4,6)为结点2。求树中两个结点的最低公共祖先是面试中经常出现的一个问题。一般的做原创 2015-02-02 12:58:47 · 2990 阅读 · 0 评论 -
[算法系列之三十二]1的数目
题目Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n.For example:Given n = 13,Return 6, because digit 1 occurred in the following num转载 2015-07-19 10:51:25 · 1727 阅读 · 0 评论 -
[算法]二分查找算法
【思想】二分搜索主要解决的问题是确定排序后的数组x[0,n-1]中是否包含目标元素target。二分搜索通过持续跟踪数组中包含元素target的范围(如果target存在数组中的话)来解决问题。一开始,这个范围是整个数组,然后通过将target与数组中的中间项进行比较并抛弃一半的范围来缩小范围。该过程持续进行,直到在数组中找到target或确定包含target的范围为空时为止。在有原创 2015-01-03 17:19:48 · 1748 阅读 · 0 评论 -
[算法]二叉树创建
【链式存储结构】struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {}};【层次创建二叉树】// 创建二叉树TreeNode* CreateTreeByLevel(vector nu原创 2014-12-30 11:32:35 · 2765 阅读 · 0 评论 -
[算法系列之三]二叉树中序前序序列(或后序)求解树
这种题一般有二种形式,共同点是都已知中序序列。如果没有中序序列,是无法唯一确定一棵树的。已知二叉树的前序序列和中序序列,求解树。1、确定树的根节点。树根是当前树中所有元素在前序遍历中最先出现的元素。2、求解树的子树。找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树。若根节点左边或右边为空,则该方向子树为空;若根节点边和右边都为空,原创 2014-05-03 09:18:27 · 3065 阅读 · 0 评论 -
[算法系列之六]二叉查找树
【简介】二叉查找树是一种数据结构,它支持多种动态集合操作。在二叉查找树上执行的基本操作的时间与树的高度成正比。对于一棵含有n个节点的完全二叉树,这些操作的最坏情况运行时间为O(n)。【结构体】一棵二叉查找树按二叉树结构来组织的。// 二叉查找树节点struct TreeNode { int val; TreeNode *left; Tree原创 2015-01-02 15:21:40 · 1920 阅读 · 0 评论 -
[算法系列之十九]最长公共子序列
有两个字符串S1和S2,求一个最长公共子串,即求字符串S3,它们同时是S1和S2的子串,且要求它们的长度最长,并确定这个长度。这个问题我们称之为最长公共子序列问题。 与求最长递增子序列一样,我们首先将原问题分割成一些子问题,我们用dp[i][j]表示S1中前i个字符和S2中前j个字符分别组成的两个前缀字符串的最长公共子串长度。显然的,当i,j较小时我们可以直接给出答案,如dp原创 2015-02-12 14:11:43 · 2281 阅读 · 0 评论 -
[算法系列之三十三]杨氏矩阵
编写一个有效的算法,搜索一个值在一个n x m表(二维数组)。这张表是沿着行和列进行--排序,也就是: Table[i][j] ≤ Table[i][j + 1], Table[i][j] ≤ Table[i + 1][j]为了运行时间复杂度的分转载 2013-11-28 23:15:26 · 3159 阅读 · 0 评论 -
[算法系列之七]Manacher算法之最大回文子串
回文串定义:“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。回文子串,顾名思义,即字符串中满足回文性质的子串。经常有一些题目围绕回文子串进行讨论,比如 HDOJ_3068_最长回文,求最长回文子串的长度。朴素算法是依次以每一个字符为中心向两侧进行扩展,显然这个复杂度是 O(N^2)的,关于字符串的题目常用的算法有 KMP、后缀数组、 A转载 2014-10-23 09:45:02 · 4644 阅读 · 3 评论 -
[算法系列之二十八]并查集(不相交集合)
一 概述并查集(Disjoint set或者Union-find set)是一种树型的数据结构,常用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。有一个联合-查找算法(union-find algorithm)定义了两个操作用于此数据结构:Find:确定元素属于哪一个子集。它可以被用来确定两个元素是否属于同一子集。Union:将两个子集合并成同一个集合。因为它支持这两种操作原创 2015-03-14 22:29:46 · 4056 阅读 · 0 评论 -
[算法系列之九]Karatsuba快速相乘算法
【概述】Karatsuba乘法是一种快速乘法。此算法在1960年由Anatolii Alexeevitch Karatsuba 提出,并于1962年得以发表。此算法主要用于两个大数相乘。普通乘法的复杂度是n2,而Karatsuba算法的复杂度仅为3nlog3≈3n1.585(log3是以2为底的)【步骤】Karatsuba算法主要应用于两个大数的相乘,原理是将大数分成两段后变成较小原创 2015-01-28 18:45:50 · 18360 阅读 · 2 评论 -
[算法]素数筛法
【方法一】【代码一】[cpp] view plaincopy//判断是否是一个素数 int IsPrime(int a){ //0,1,负数都是非素数 if(a return 0; } //计算枚举上界,为防止double值带来的精度损失原创 2014-12-10 15:18:27 · 1283 阅读 · 1 评论 -
[算法系列之十]大数据量处理利器:布隆过滤器
【引言】在日常生活中,包括在设计计算机软件时,我们经常要判断一个元素是否在一个集合中。比如在字处理软件中,需要检查一个英语单词是否拼写正确(也就是要判断 它是否在已知的字典中);在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上;在网络爬虫里,一个网址是否被访问过等等。最直接的方法就是将集合中全部的元素存在计算机中,遇到一个新 元素时,将它和集合中的元素直接比较即可。一般来讲,计算机中的集合是用原创 2015-02-04 12:39:11 · 6952 阅读 · 1 评论 -
[算法]字符串消除问题的数学证明
问题:给定一个字符串,仅由A、B、C3个字母组成。当出现连续两个不同的字母时,你可以用另外一个字母替换它,如有AB或BA连续出现,你把它们替换为字母C;有AC或CA连续出现时,你可以把它们替换为字母B;有BC或CB连续出现时,你可以把它们替换为字母A。可以不断反复按照这个规则进行替换,目标是使得最终结果所得到的字符串尽可能短,求最终结果的最短长度。输入:字符串。长度不超过200,仅转载 2014-12-10 15:20:16 · 1188 阅读 · 0 评论 -
经典算法之计数排序
一 引言计数排序假设n个输入元素中的每一个都是介于0-k的整数,此处k为某个整数。当k等于O(n)时,计数排序的运行时间为Θ(n)。二 基本思想计数排序的基本思想就是对每一个输入元素x,确定小于x的元素个数。因此我们就可以直接把x放到最终输出数组中的相应位置上。例如:如果有17个元素小于x,则x就位于第18个输出的位置上。当然有几个元素相同时,这个方法就略微改进一下原创 2014-04-26 19:18:39 · 4243 阅读 · 0 评论 -
经典白话算法之归并排序
void Merge(int A[],int p,int q,int r){ int i,j,k; //计算子数组A[p..q]的元素个数 int n1 = q - p + 1; //计算子数组A[q+1..r]元素个数 int n2 = r - q; //创建子数组L,R int* L = (int*)malloc(sizeof(int)*原创 2014-05-03 09:43:24 · 1978 阅读 · 1 评论 -
经典白话算法之中缀表达式和后缀表达式
一、后缀表达式求值后缀表达式也叫逆波兰表达式,其求值过程可以用到栈来辅助存储。假定待求值的后缀表达式为:6 5 2 3 + 8 * + 3 + *,则其求值过程如下:(1)遍历表达式,遇到的数字首先放入栈中,依次读入6 5 2 3 此时栈如下所示:(2)接着读到“+”,则从栈中弹出3和2,执行3+2,计算结果等于5,并将5压入到栈中。原创 2014-05-03 09:17:12 · 1393 阅读 · 0 评论 -
经典白话算法之冒泡排序
简化版的桶排序不仅仅有上一节所遗留的问题,更要命的是:它非常浪费空间!例如需要排序数的范围是0~2100000000之间,那你则需要申请2100000001个变量,也就是说要写成int a[2100000001]。因为我们需要用2100000001个“桶”来存储0~2100000000之间每一个数出现的次数。即便只给你5个数进行排序(例如这5个数是1,1912345678,2100000000,1转载 2014-05-01 20:53:27 · 1147 阅读 · 0 评论 -
[算法系列之十三]Rabin-Karp字符串查找算法
Michael O. Rabin和Richard M. Karp在1987年提出一个想法,即可以对模式串进行哈希运算并将其哈希值与文本中子串的哈希值进行比对。总的来说这一想法非常浅显,唯一的问题在于我们需要找到一个哈希函数 ,它需要能够对不同的字符串返回不同的哈希值。例如,该哈希函数可能会对每个字符的ASCII码进行算,但同时我们也需要仔细考虑对多语种文本的支持。转载 2015-02-05 21:33:27 · 2554 阅读 · 0 评论 -
[算法系列之十四]字符串匹配之Morris-Pratt字符串搜索算法
前言我们前面已经看到,蛮力字符串匹配算法和Rabin-Karp字符串匹配算法均非有效算法。不过,为了改进某种算法,首先需要详细理解其基本原理。我们已经知道,暴力字符串匹配的速度缓慢,并已尝试使用Rabin-Karp中的一个散列函数对其进行改进。问题是,Rabin-Karp的复杂度与强力字符串匹配相同,均为O(mn)。我们显然需要采用一种不同方法,但为了提出这种不同方法,先来看看暴力字符串匹配有什么不翻译 2015-02-06 09:56:06 · 2069 阅读 · 0 评论 -
[算法系列之十二]字符串匹配之蛮力匹配
引言字符串匹配是数据库开发和文字处理软件的关键。幸运的是所有现代编程语言和字符串库函数,帮助我们的日常工作。不过理解他们的原理还是比较重要的。字符串算法主要可以分为几类。字符串匹配就是其中之一。当我们提到字符串匹配算法,最基本的方法就是所谓的蛮力解法,这意味着我们需要检查每一个文本串中的字符是否和匹配串相匹配。一般来说我们有文本串和一个匹配串(通常匹配串短于文本串)。我们需要做的就是回答这个匹配串是原创 2015-02-05 20:46:45 · 6777 阅读 · 0 评论 -
[算法系列之二十四]后缀树(Suffix Tree)
之前有篇文章([算法系列之二十]字典树(Trie))我们详细的介绍了字典树。有了这些基础我们就能更好的理解后缀树了。一 引言 模式匹配问题给定一个文本text[0…n-1], 和一个模式串 pattern[0…m-1],写一个函数 search(char pattern[], char text[]), 打印出pattern在text中出现的所有位置(n > m)。这个问题已经有两个经典的算法:原创 2015-02-27 19:03:47 · 11509 阅读 · 0 评论 -
[算法系列之二十五]Ukkonen后缀树算法
所以我们从左边开始,第一次只插入单字符”a”,通过创建一个从根节点到一个叶节点的边(根节点左边),并且标记这条边[0,#],意思是说这条边代表了从0开始到当前末尾的子串。我使用#来表示当前末尾,当前末尾处在位置1(a的右边)。因此,我们拥有一棵起始树,图示如下:图示意思为:插入单字符”b”。当前末尾位置前进到位置2(b的右边)。 我们每步的目的是就是把所有的前缀都插入到当前位置(Our goal a转载 2015-02-28 15:30:58 · 4436 阅读 · 0 评论 -
[算法系列之二十二]包含T全部元素的最小子窗口
题目描述给定一个包含一系列字符的集合T和字符串S,请在字符串S中找到一个最小的窗口,这个窗口中必须包含T中的所有字符。 例如, S = “ADOBECODEBANC” T = “ABC”最小窗口是“BANC”分析这是一个有趣的问题,这个有趣的问题有多种方法来解决,最好的方法是非常简单,美丽的。 在这篇文章中,我首先说明了一个方法,是我第一次遇见这个问题时想到的。我的第一个方法有点复杂,同时也翻译 2015-02-24 11:41:02 · 3395 阅读 · 0 评论 -
[算法系列之二十一]最短摘要的生成
题目描述你我在百度或谷歌搜索框中敲入本博客名称的前4个字“结构之法”,便能在第一个选项看到本博客的链接,如下图2所示: 图2 谷歌中搜索关键字“结构之法”在上面所示的图2中,搜索结果“结构之法算法之道-博客频道-CSDN.NET”下有一段说明性的文字:“程序员面试、算法研究、编程艺术、红黑树4大经典原创系列集锦与总结 作者:July–结构之法算法…”,我们把这段文字称为那个搜索结果的摘要,亦即转载 2015-02-23 16:36:14 · 2597 阅读 · 1 评论 -
[算法系列之二十]字典树(Trie)
又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。二 优点利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。三 性质(1)根节点不包含字符,除根节点外每一个节点都只包含一个字符; (2)从根节点到某一节点,路径上经过的字符连接起来,为原创 2015-02-21 22:26:18 · 7673 阅读 · 0 评论