算法与数据结构
文章平均质量分 85
wyc_
技术之路是千里之行,莫功利方能行更远
展开
-
拓扑排序实例
在前面的文章《深度优先搜索》中介绍了拓扑排序,这里看两道相关题目1.Course ScheduleThere are a total of n courses you have to take, labeled from 0 ton - 1.Some courses may have prerequisites, for example to take course 0 y原创 2016-03-09 10:31:47 · 2737 阅读 · 0 评论 -
动态规划专题(I)
动态规划与分治法类似,都是通过组合子问题的解来求解原问题。分治方法将问题划分为互不相交的子问题,递归的求解子问题,再将它们组合起来,求出原问题的解。与之相反,动态规划应用于子问题重叠的情况,不同的子问题具有公共的子子问题。这个时候,分治算法会做许多不必要的工作,它会反复的求解那些公共子子问题,而动态规划则对每个子问题只求解一次。举例来说,在之前的文章《排序算法总结》中,我们介绍了一些采用分治策略的原创 2014-11-19 10:36:13 · 619 阅读 · 0 评论 -
贪心算法 II
上一篇文章中介绍了贪心算法,并给出了几个题目的分析证明,其中“Gas Station”那道题的难度比较大,但是让我们很好的体会到贪心算法的用武之地,同时也体会到证明的重要性,贪心算法并不能保证得到的一定是最优解,一定要得到证明方可放心使用。本篇继续介绍贪心算法实例。1. 活动选择问题假定有一个n个活动的集合S={a1,a2,...,an},这些活动使用同一个资源,而这个资源在某个时刻只能供原创 2014-10-17 17:34:04 · 849 阅读 · 0 评论 -
多源最短路径--Floyd-Warshall算法
上一篇文章《所有节点对的最短路径问题》中我们介绍到了Floyd-Warshall算法,由于代码较长,没有放到上一篇文章中,我们在这里单独给出Java实现的代码。 import java.util.*; class Floyd_Warshall { static final int MAX = 20; //最大点数 s原创 2015-01-21 21:06:05 · 544 阅读 · 0 评论 -
动态规划专题(III)
接上一篇11. Minimum Path SumGiven a m x n grid filled with non-negative numbers, find a path from top left to bottom right whichminimizes the sum of all numbers along its path.Note: You can on原创 2014-11-19 17:20:10 · 892 阅读 · 0 评论 -
动态规划专题(II)
1.钢条切割问题长度i 1 2 3 4 5 6 7 8原创 2014-11-19 10:37:47 · 609 阅读 · 0 评论 -
并查集
并查集:一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。对于数组中的元素,我们如何表示元素a与元素b属于一个集合呢?比较容易想到的方法就是如果两个元素属于同一个集合,我们就将对应下标的数组中的值设为一个相同的标记来表示。为了区分不同的集合,每个集合的标记都应该是唯一的,一个比较好的方法就是取该标记为集合元素的最小值。我们看一下查找的过程,假设该数组为father[MAX],原创 2014-10-10 17:17:59 · 505 阅读 · 0 评论 -
排列组合程序
1.Next PermutationImplement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.If such arrangement is not possible, it must rearrange it as原创 2014-10-29 10:42:20 · 839 阅读 · 0 评论 -
递归程序实例
//请问如下代码的输出是什么?import java.rmi.UnexpectedException;public class WanWanMeiXiangDao{ public static void main(String[] args) { try(DaChuiCareer daChui = new DaChuiCareer()){ daChui.happyLife()原创 2015-04-18 21:27:53 · 474 阅读 · 0 评论 -
最小生成树
1.理论首先还是要搞清研究对象,简单说最小生成树问题就是找一个无环子集,它既能把所有的节点连接起来,又具有最小的权重。下面介绍一些定义切割:无向图G=(V,E)的一个切割(S,V-S)是集合V的一个划分。如果一条边(u,v) in E的一个端点位于S,另一个端点位于V-S,则称该边横跨切割(S,V-S)。如果集合A中不存在横跨该切割的边,则称该切割尊重集合A。在横跨一个切割原创 2014-12-20 21:32:16 · 705 阅读 · 0 评论 -
所有节点对的最短路径问题
前面在《单源最短路径》中我们接触了最短路径问题,并介绍了求解最短路径问题的算法,比如Bellman-Ford算法,Dijkstra算法。不过,那里我们计算的是从一个固定的源节点到所有其他点的最短路径。假如我们要想求任意节点对之间的最短路径呢?一个方法是以所有节点作为源节点调用上述比如Dijkstra算法,如果使用二叉堆实现最小优先队列时间复杂度为O(VElgV),如果使用斐波那契堆来实现最小优先队原创 2015-01-15 19:37:49 · 6544 阅读 · 0 评论 -
单源最短路径
1.基础最短路径简单说就是,一个带权重的有向图,图中从u到v的最短路径就是所有从u到v的路径中权重之和最小的。最短路径具有最优子结构:两个节点之间的最短路径包含着其他的最短路径。这使得我们可以用动态规划或贪心算法来解决该问题。最短路径可以包含负权重的边,但是不能包含权重为负值的环路。当然也不能包含权重为正值的环路。下面介绍比较重要的最短路径和松弛操作的性质:三角不等式性质:原创 2014-12-22 16:33:02 · 957 阅读 · 0 评论 -
字符串匹配
在前面的《最长公共子序列LCS问题》中,我们采用动态规划求解了两个字符串的最长公共子序列的问题,在《最长公共子串》中,我们又用动态规划解决了两个字符串的最长公共子串问题。其中公共子序列问题更加一般,它不要求匹配结果是连续的,公共子串相对特殊一点,它要求匹配连续的子串,二者都不要求其中一个字符串必须完全匹配。在《字典树》中,我们知道字典树也可以用来高效匹配字符串,首先它要求从头开始匹配,其次它匹配的原创 2015-04-11 15:39:58 · 1179 阅读 · 0 评论 -
二叉树 字典树
昨晚偶然看到了字典树,今天把二叉树与字典树的内容原创 2014-10-14 19:35:06 · 1371 阅读 · 1 评论 -
深度优先搜索实例
前面文章《深度优先搜索》中介绍了深度优先搜索的相关知识,现在看一些实例,来加深理解运用。以下问题中涉及到的树的结构如下/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode ri原创 2014-12-16 10:39:51 · 3188 阅读 · 0 评论 -
一个全新的视角来看KMP算法(简单!形象!)
前面《字符串匹配》中我们介绍了KMP算法,《KMP算法Java实现》中给出了KMP算法的实现。KMP算法很多人都说难,我第一次从《算法导论》中看到的时候也觉得难,后来重看算导时自己推导了一遍,觉得不难了,但是还是感觉印象不深,推导过后一段时间又会很模糊,下次遇到又得重新推。KMP算法原理上并不难,但是之所以给人难的感觉是因为它不够直观。今天突发奇想想到了一种将KMP算法图形化的方法,我原创 2016-07-23 09:53:18 · 1499 阅读 · 0 评论 -
KMP算法Java实现
之前的文章《字符串匹配》中介绍了KMP算法,下面给出其Java实现。public class KMP{ static final int MAX = 100; static int[] pi = new int[MAX]; //第一种方法 /** 思路:遍历T中的每一个字符,如果与P中的匹配,则二者游标递增,增到P的长度说明已经匹配,返回true * 如果不匹配,分两种情况原创 2015-10-25 18:45:41 · 403 阅读 · 0 评论 -
寻找最近点对
本文是关于在n>=2个点的集合Q中寻找最近点对的问题。容易想到的暴力手段,需要遍历theta(n^2)个点对,效率不高。本文中给出一种时间复杂度为O(nlgn)的算法,算法采用分治策略。下面具体描述:输入为P、X和Y,其中P是Q的子集,数组X包含P的所有点,并按照x坐标单调递增,同样Y中的点按照y坐标排序。为了维持O(nlgn)的时间界,不能在每次递归调用中都排序,否则运行时间递归式就原创 2015-11-16 15:26:11 · 451 阅读 · 0 评论 -
数据结构:数组+链表(巧妙!)
数组+链表这种数据结构在《HashMap源码分析》一文中以及在之前分析Linux内核源码的过程中多次碰到,本篇文章专门探讨这种数据结构。数组与链表各自的优缺点大家肯定都很熟悉了,而数组+链表这种数据结构其实是综合了二者之间的优点,这类似于A*算法综合了广度优先搜索算法与贪心算法的优点一样,这种思想应用比较广,一定要掌握。再举个例子,比如我们知道遗传算法收敛速度比较慢,但是爬山法的收敛速原创 2016-07-18 19:12:37 · 20043 阅读 · 0 评论 -
LUP分解求解线性方程组及求逆矩阵 java
具体的分析参考算法导论public class LU{ /**矩阵相乘*/ public static float[][] multiply(float[][]A,float[][]B){ int n = A[0].length,i = 0,j = 0,k = 0; float[][] C = new float[n][n]; for(i = 0;i < n;i++)原创 2015-11-22 19:07:50 · 3891 阅读 · 1 评论 -
判定两条线段是否相交
首先介绍一下非常重要的关于叉积的概念,它是线段方法的核心。可以把叉积解释成由点(0,0),p1,p2和p1+p2=(x1+x2,y1+y2)所构成的平行四边形的有向面积,也可以看做是矩阵行列式:根据P_{1}与P_{2}的叉积,我们就能判断p_{2}是在P_{1}的顺时针方向还是逆时针方向。下面给出的是判断两条是否相交的代码主要注意这里判定的是线段,而不是直线。1.在直原创 2015-10-24 21:11:12 · 815 阅读 · 0 评论 -
并查集II
1. Longest Consecutive SequenceGiven an unsorted array of integers, find the length of the longest consecutive elements sequence.For example,Given [100, 4, 200, 1, 3, 2],The longest consecutiv原创 2014-10-10 19:58:53 · 398 阅读 · 0 评论 -
字典树应用
1.HDU1004 Let the Balloon RiseTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 75817 Accepted Submission(s): 28455Problem Descri原创 2014-10-15 19:23:09 · 453 阅读 · 0 评论 -
贪心算法
1.算法简介贪心算法在每一步都做出在当前看来最优的选择,希望能通过局部最优找到全局最优。因此使用贪心算法来找最优解还需要证明它的确能得到全局最优解,通常可以用反证法加以证明。贪心算法在解决一些问题的时候会比动态规划更加方便,有很多基于贪心策略设计的算法,比如最小生成树算法,单源最短路径的Dijkstra算法,实际上A*算法中的启发式信息也可以看成是贪心策略的应用。下面还是通过实际的问题原创 2014-10-16 18:57:30 · 657 阅读 · 1 评论 -
HDU1003 Max Sum
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 149471 Accepted Submission(s): 34914Problem DescriptionGiven a sequence a[1],a[2],a原创 2014-10-23 09:54:19 · 376 阅读 · 0 评论 -
线段树-两道题
Time Limit: 30000/15000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1669 Accepted Submission(s): 734Problem DescriptionThere is an old country an原创 2014-10-30 11:29:15 · 408 阅读 · 0 评论 -
母函数模板
一开始以为很简单的,结果还是稍有复杂。结合网上的资料总结一下。求用1分、2分、3分的邮票贴出不同数值的方案数:学过组合数学很容易写出其母函数:G(x)=(1+x+x^2+x^3+....)(1+x^2+x^4+....)(1+x^3+x^6+....)下面给出该类母函数的模板:#include using namespace std;#define max 100原创 2014-10-30 17:23:43 · 435 阅读 · 0 评论 -
HDU1028 Ignatius and the Princess III(母函数)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 13388 Accepted Submission(s): 9459Problem Description"Well, it seems the first prob原创 2014-10-30 18:04:28 · 303 阅读 · 0 评论 -
HDU4960 Another OCD Patient
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1147 Accepted Submission(s): 409Problem DescriptionXiaoji is an OCD (obsessive-原创 2014-11-06 10:50:39 · 594 阅读 · 0 评论 -
HDU4901 The Romantic Hero
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1415 Accepted Submission(s): 599Problem DescriptionThere is an old country and th原创 2014-11-06 16:30:55 · 309 阅读 · 0 评论 -
HDU Clear All of Them I(状态压缩+DP+记忆搜索)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 122768/62768 K (Java/Others)Total Submission(s): 1556 Accepted Submission(s): 509Problem DescriptionAcmers have been the Earth Prot原创 2014-11-09 19:44:55 · 382 阅读 · 0 评论 -
三维动态规划 To The Max
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8503 Accepted Submission(s): 4127Problem DescriptionGiven a two-dimensional array原创 2014-11-22 18:05:16 · 2228 阅读 · 0 评论 -
广度优先搜索
一、基础广度优先搜索需要注意的几点:1)需要对已经入队过的节点予以标记,防止进入死循环。这相当于《算法导论》伪代码中对节点进行着色的操作。2)广度优先搜索一定可以找到每一点到原点的最短路径,这里的最短路径只得是边的条数,如果我们要找一条权重之和最短的路径,依然可以用广度优先搜索算法。为了回溯信息,需要定义一个father数组,指向每个元素的父节点。代码见下面2import java.u原创 2014-12-06 17:34:04 · 818 阅读 · 0 评论 -
稀疏图Johnson算法
在前面的文章《所有节点对的最短路径问题》中,我们介绍了用于稀疏图的Johnson算法,由于代码比较长,我们将其单独放在一篇文章之中。Johnson算法的时间复杂度在使用二叉堆作为最小优先队列的情况下为O((V^2 + EV)lgV);在使用斐波那契堆作为最小优先队列的时候为O(V^2lgV + VE),因此尤其是在稀疏图的情况下,其效率要比Floyd-Warshall高。下面给出Java实原创 2015-01-28 10:53:34 · 3272 阅读 · 1 评论 -
最大流
1.流网络流网络G=(V,E)是一个有向图,图中每条边(u,v) in E有一个非负的容量值 c(u,v) >= 0。而且如果边集合E包含一条边(u,v),则图中不存在反向边(v,u)。在流网络的所有节点中,比较特殊的是源节点s和汇节点t,为了方便起见,假定每个节点都在源节点到汇节点的路径上,也就是说,流网络图是连通的。对于流,比较重要耳朵两条性质是:容量限制和流量守恒,流f的值是从源节点流出原创 2015-01-29 12:09:34 · 624 阅读 · 0 评论 -
Ford-Fulkerson算法 java实现
/*for each edge(u,v) 属于 G,E(u,v).f = 0;while there exists a path p from s to t in the residual network Gfcf(p) = min{cf(u,v):(u,v) is in p};for each edge(u,v) in pif(u,v)属于E(u,v).f += cf原创 2015-10-22 18:48:08 · 1746 阅读 · 0 评论 -
深度优先实现拓扑排序--java
import java.util.*;public class Topology{ static final int MAX = 20; //最大点数 static int[][] g; //图 static LinkedList queue; //保存排序结果 static int[] ingoing; //记录节点入度 static int[] outgoing;//记录节点出原创 2015-10-23 09:38:31 · 2810 阅读 · 0 评论 -
寻找凸包-graham扫描法
Graham扫描法通过维持一个关于候选点的栈S来解决凸包问题。输入集合Q中的每个点都被压栈一次,非CH(Q)中的点最终被弹出栈。当算法终止时,栈S仅包含CH(Q)中的顶点,以逆时针的顺序出现在边界上。该算法最核心的一点就是,逆时针方向遍历凸包时,应该在每个顶点处左转。import java.util.*;public class Graham{ static int MAX = 10原创 2015-10-24 19:22:05 · 1324 阅读 · 0 评论 -
排序算法总结
在实际中待排序的数很少是单独的数值,它们通常是被称为记录的数据集的一部分。每个记录包含一个关键字,就是排序问题中要重排的值。记录的剩余部分由卫星数据组成,通常与关键字是一同存取的。如果每个记录包含大量的卫星数据,我们通常重排记录指针的数组,而不是记录本身,这样可以降低数据移动量。如果输入数组中仅有常量个元素需要在排序过程中存储在数组之外,则称排序算法是原址的。以下排序算法的原理并不做过原创 2014-10-20 20:58:20 · 691 阅读 · 0 评论