数据结构与算法
文章平均质量分 72
学习数据结构与算法,共同进步!!!
Rebright-崇明
神说要有光,于是便有了我
展开
-
图论算法(五)--求解割点、割边(JAVA)
割点:对于一个连通图来说,如果删除某个点之后图不再连通,这个点就称为割点 割点算法 时间复杂度:O(N+M) 但是下面给出的算法时间复杂度为O(N^2),这是因为下面的存储结构都是邻接矩阵,这样的话用该算法就完全失去了意义,毕竟如果使用邻接矩阵完全可以通过删除一个点,然后进行DFS/BFS遍历即可了。所以在实际应用中还是要使用邻接表来保存数据,这样时间复杂度可以达到O(N+M) Input原创 2018-01-12 22:45:06 · 1860 阅读 · 0 评论 -
图论算法(六)-- 二分图的最大分配问题(JAVA)
二分图:又称二部图,如果一个图的所有顶点可以被分为X和Y两个集合,并且所有边的两个顶点恰好一个属于一个集合X,另一个属于集合Y,即每个集合内的顶点没有边相连,那么这个图就是二分图。 二分图的最大分配问题就是,在所有的分配中,可以输出分配数最多的,但是这样的求解方式效率很低。下面我们引入“增广路”的概念 增广路的本质就是一条路径的起点和终点都是未被配对的点,增加一条增广路就是增加一条配对路线。而原创 2018-01-12 23:00:56 · 1847 阅读 · 0 评论 -
斐波那契数列(二)--矩阵优化算法
之前写了一篇从斐波那契数列分析递归与动态规划(JAVA)来优化斐波那契数列,这样可以使算法的时间复杂度从O(n^2)变到O(n),这是使用递归公式f(n)=f(n-1)+f(n-2)求斐波那契数列的最优算法,但是这只是一维世界下的极限。下面我们将其从一维上升到二维,用二阶矩阵推导斐波那契数列,该算法的复杂度为O(logn)。矩阵定义一个m*n的矩阵是一个由m行n列元素排成的矩形阵列。矩阵里的元素可...原创 2018-01-18 12:23:19 · 4256 阅读 · 0 评论 -
从背包问题优化详解动态规划思想
动态规划:所有的数据结构与算法的理解必须建立在题目的练习上,否则看多少理论都没有实际用处!!!所以下面这些理论文字看不懂通通没关系,跟随下面的背包问题还会跟深入的理解。一、基本概念:任何数学递推公式都可以直接转换成递归算法,但是基本现实是编译器常常不能正确对待递归算法,结果导致低效的程序。当怀疑很可能是这种情况是,我们必须给编译器提供一些帮助,将递归算法重新写成非递原创 2018-01-23 19:10:14 · 1027 阅读 · 0 评论 -
深入浅出讲算法思想--蛮力法思想分析及应用
蛮力法(brute force method,也称为穷举法或枚举法)是一种简单直接地解决问题的方法,常常直接基于问题的描述,所以,蛮力法也是最容易应用的方法。虽然,用蛮力法设计的算法时间特性往往也是最低的,但是许多问题我们一开始并没有很优化的算法,而蛮力法则可以帮助我们从低效的算法结构中剖析低效的缘由,进而提炼出更为优化的算法。蛮力法在排序算法中的应用(选择,冒泡)蛮力法在查找算法中的原创 2018-02-01 20:20:20 · 10239 阅读 · 0 评论 -
减治法解决八枚硬币问题/假币问题(JAVA)----二分,三分,不知轻重的情况
八枚硬币问题在八枚外观相同的硬币中,有一枚是假币,并且已知假币与真币的重量不同,但不知道假币与真币相比较轻还是较重。可以通过一架天平来任意比较两组硬币,设计一个高效的算法来检测出这枚假币。我们先假设一个条件:已知假币比真币轻二分查找算法实现:时间复杂度(O(log(以2为底n的对数)))思路:把n枚硬币分成两堆,每堆有枚硬币,如果原创 2018-02-02 22:33:40 · 8056 阅读 · 1 评论 -
减治法在查找算法中的应用(JAVA)--折半查找
减治法在查找算法中的应用折半查找:(时间复杂度O(log以2为底n的对数))对于有序数组的查找来说,折半查找是一种非常高效的算法,其基本原理为:比较查找键k和数组中间元素a[m],如果相等,算法结束;如果k<a[m],对数组前半部分执行操作;如果k>a[m],对数组后半部分执行操作。public class Main { static int k = 89;...原创 2018-02-03 17:07:17 · 867 阅读 · 1 评论 -
减治法解决约瑟夫斯问题(JAVA)
减治法在查找算法中的应用问题背景:据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想原创 2018-02-03 17:19:57 · 1161 阅读 · 1 评论 -
减治法在查找算法中的应用(JAVA)--快速查找
减治法在查找算法中的应用快速查找:选择问题是求一个n个数列表的第k个最小元素的问题,这个数k被称为顺序统计量。对于k=1或k=n来说,这并没有什么意义,我们通常会要找出这样的元素:该元素比列表中一半元素大,比另一半元素小,这样的元素被称为中值。我们当然可以对列表进行排序,之后找出对应下标的值,但是!!!这样一个查找问题,反而要对整个列表排序,是不是有点多余了呢?这里引入划分的概念我们可原创 2018-02-03 17:24:56 · 1657 阅读 · 0 评论 -
减治法在查找算法中的应用(JAVA)--二叉查找树的查找、插入、删除
减治法在查找算法中的应用二叉查找树的查找与插入:二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:(1)若左子树不空,则左子树上所有结点的值均小于或等于它的根节点的值;(2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;(3)左、右子树也分别为二叉排序树。对于二叉查找树这里我们介绍查找、插入和删除操作:这些操作会将问题的规模变成一个更小的二原创 2018-02-03 17:29:00 · 975 阅读 · 0 评论 -
减治法在排序算法中的应用(JAVA)--插入排序
一、减治法在排序算法中的应用插入排序:时间复杂度O(n^2),虽然和选择、冒泡在最坏的情况下时间复杂度相同,但是插排平均性能在比自身的最差性能快一倍,所以相比选择、冒泡来说,插排要领先于二者。public class Main { public static void main(String[] args) { int[] a = {89, 45, 68, 90原创 2018-02-03 17:33:13 · 1319 阅读 · 0 评论 -
减治法在求解拓扑排序问题中的应用(JAVA)--有向无环图
减治法在求解拓扑排序问题中的应用拓扑排序:对于一个有向无环图来说,如果我们能够按照次序列出顶点,使得对于每条边来说,边的起始顶点总是排在边的结束顶点之前,那么这个过程就称为拓扑排序,拓扑排序有解是一个图是有向无环图的充要条件。基于减治法的拓扑排序,基本原理是源删除,每次寻找一个入度为0的点,根据这个点的出度找到下一个点,然后删除这个点和所有的所有出度,再继续迭代操作。public原创 2018-02-03 17:48:32 · 992 阅读 · 0 评论 -
减治法在生成全排列中的应用(JAVA)--回溯、Johnson-Trotter算法、自字典序
减治法在生成组合对象问题中的应用在深入浅出讲算法思想--蛮力法思想分析及应用这篇文章的最优解问题中中已经初步讲解了这类应用,下面我们将使用减治法再次思考这类问题。1、全排列问题,在数学中求解一个n个数组合的全排列问题会产生n!个组合的情况。暴力枚举的确是个方法,但是除非n非常的小,不然这个时间复杂度是非常庞大的,但是如果运用减治思想就可以解决这种问题,我们便可以将我们可以将生成n!个排原创 2018-02-03 17:53:58 · 1124 阅读 · 0 评论 -
减治法在生成子集问题中的应用(JAVA)--递归、二进制反射格雷码
减治法在生成组合对象问题中的应用生成子集问题:经典的背包问题就是求解一个最优子集的问题,这里我们来讨论一个更简单的问题。对于任意一个集合来说,它都存在2^n个子集(一个集合所有的子集集合称为幂集)。1)简单递归实现:import java.util.ArrayList;import java.util.List;public class Main { publi原创 2018-02-03 17:57:31 · 1021 阅读 · 0 评论 -
减治法解决俄式乘法问题(JAVA)
以上是在《算法设计与分析基础》一书中给出的定义。这种算法只包括折半、加倍、相加这几个操作,在计算时,不需要用九九乘法表 。同时,这个方法每次都会将计算的规模减少,运用了减治的思想public class Main { public static void main(String[] args) { int result = RusseMul(24,32)...原创 2018-02-03 19:25:54 · 1041 阅读 · 0 评论 -
减治法解决尼姆(Nim)游戏/拈游戏问题(JAVA)
尼姆游戏是一种两个人玩的回合制数学策略游戏。游戏者轮流从一堆棋子(一共有好几堆,一次只能从其中一堆拿。)(或者任何道具)中取走一个或者多个,最后不能再取的就是输家。当指定相应数量时,一堆这样的棋子称作一个尼姆堆。尼姆游戏有很多形式,也可以说很多游戏的原型都是尼姆游戏。单堆尼姆游戏:假设我们现在有一堆n枚棋子,两个玩家轮流从堆中拿走至少1枚,至多m枚棋子。每次拿走的棋子数都可以不同,原创 2018-02-03 21:38:35 · 2712 阅读 · 0 评论 -
蛮力法在排序算法中的应用(JAVA)--选择排序、冒泡排序
蛮力法在排序算法中的应用对于一个排序问题,我们能想到的最简单的排序方法就是选择和冒泡1、选择排序:时间复杂度O(n^2)public class Main { public static void main(String[] args) { int[] a = {89, 45, 68, 90, 29, 34, 17}; int min;原创 2018-02-04 10:27:33 · 1405 阅读 · 0 评论 -
蛮力法在查找算法中的应用(JAVA)--顺序查找
蛮力法在查找算法中的应用对于查找算法来说,最简单的一个思路就是逐个匹配,直到找到目标元素顺序查找:public class Main { public static void main(String[] args) { int[] a = {89, 45, 68, 90, 29, 34, 17, 0}; int k = 45;原创 2018-02-04 10:27:51 · 357 阅读 · 0 评论 -
蛮力法在字符串匹配问题中的应用(JAVA)--朴素模式匹配算法
蛮力法在字符串匹配问题中的应用字符串匹配问题通常是给定一个n个字符组成的串(称为文本),一个m(m<=n)个字符的串(称为模式),从文本中寻找匹配模式的子串。显然我们需要逐个匹配,这是蛮力算法的典型特点。蛮力匹配:时间复杂度O(n^2)public class Main { public static void main(String[] args) { String...原创 2018-02-04 10:28:03 · 1389 阅读 · 0 评论 -
蛮力法在求解“最近对”问题中的应用(JAVA)
最近对问题是在计算几何问题中最简单的,是指在一个包含n个点的集合中,找到距离最近的两个点,我们这里只研究二维空间中的版本,高维计算基本类似,区别只在于计算两点之间距离的公式略有不同,下面是标准的欧几里得距离公式:class Point { int x; int y; public Point(int x, int y) { this.x =原创 2018-02-04 10:31:23 · 2377 阅读 · 0 评论 -
蛮力法在求解凸包问题中的应用(JAVA)
凸包问题向来是计算几何中最重要的问题之一,许多各式各样的应用大多要么本身就是图凸包问题要么其中一部分需要按照凸包问题解决。凸集合定义:对于平面上一个点集合,如果集合中的任意两点p和q为端点的线段都属于该集合,那么称这个集合为凸集合。凸包定义:一个点集合S的凸包是包含S的最小凸集合。我们可以假设有一块板子,板子上面有许多钉子,用一根橡皮筋将所有的钉子都围住,凸包就是以橡皮筋圈为边界的区域。原创 2018-02-04 10:31:34 · 2401 阅读 · 1 评论 -
蛮力法在求解最优解问题中的应用(JAVA)--旅行家问题、背包问题、分配问题
蛮力法在求解最优解问题中的应用1、TSP(旅行商问题)要求我们找出一条n个给定城市之间的最短路径,使我们再回到出发的城市之前,对欧每个城市都只访问一次。我们可以用赋权图来描述这个问题,那么算法的目的就是求解一个图的最短哈密顿回路问题。哈密顿回路同样可以定义为其中第一个顶点和最后一个顶点相同,其他n-1个顶点互不相同。那么我们就可以通过生成n-1个中间城市的组合来的到所哟逇旅行线原创 2018-02-04 10:31:57 · 4434 阅读 · 5 评论 -
分治法在排序算法中的应用(JAVA)--归并排序
分治法最常用的就是将规模为n的实例划分成两个n规模为n/2的实例 。推广到一般的情况,我们可以将规模为n的实例划分为b个规模为n/b的实例。这样对于算法的运行时间存在递推式:T(n) = aT(n/b)+f(n),这个式子又被称为通用分治递推式。我们假定递推式中的f(n)∈O(n^d),其中d>=0,那么:所以,对于等分的T(n) = 2T(n/2) + 1,因为a=2,b=2,d原创 2018-02-04 16:19:35 · 781 阅读 · 0 评论 -
分治法在排序算法中的应用(JAVA)--快速排序(Lomuto划分、Hoare划分、随机化快排)
分治法在排序算法中的应用--快速排序时间复杂度:平均O(nlogn),最坏O(n^2)如果说归并排序是按照元素在数组中的位置划分的话,那么快速排序就是按照元素的值进行划分。划分方法由两种,本节将主要介绍Huare划分,这也是我们通常采用的划分方法。为了文章完整,下面只给出基于Lomuto划分的代码,详细分析请参考减治法在查找算法中的应用(JAVA)--快速查找。1、基于Lomuto...原创 2018-02-04 23:58:36 · 3669 阅读 · 0 评论 -
分治法在二叉树遍历中的应用(JAVA)--二叉查找树高度、前序遍历、中序遍历、后序遍
分治法在二叉树遍历中的应用二叉树本身就是由两个更小的部分组成--左子树和右子树,所以二叉树的问题非常适合用分治法来解决。二叉树的高度:从叶子到根之间的最长路径。我们可以理解为根的左子树高度和右子树高度加1(加1代表根所在的层)。定义空树的高度为-1private static int height(Node node) { if (node == null) {原创 2018-02-05 13:47:31 · 1275 阅读 · 0 评论 -
分治法在求解“最近对”问题中的应用(JAVA)
分治法在求解“最近对”问题中的应用最近对问题在蛮力法中有过讲解,时间复杂度为O(n^2),下面将会采用分治法讲解这类问题,时间复杂度会降到O(nlogn)我们将笛卡尔平面上n>1个点构成的集合称为P。若23时,采用分治法或许是个更好的选择。假设这些点是按照x轴、y轴升序排列的,可以找出点集在x轴方向上的中位数m,做一条垂直x轴的分割线,由此点将点集划分为左右两个大小为n/2的子集P1和P2原创 2018-02-05 20:31:12 · 1712 阅读 · 0 评论 -
搜索算法(三)--DFS/BFS求解宝岛探险问题(JAVA )
宝岛探险问题问题描述:某片海域有诸多岛屿,用0表示海洋,1-9表示陆地,现给定一个岛屿上的坐标点,求解所在岛屿的面积思路:显然这是一个搜索算法,即只要从当前坐标点开始遍历,每遍历到一个点进行计数即可,但是要注意sum的初始值为1!!!Input: 10 10 1 2 1 0 0 0 0 0 2 3 3 0 2 0 1 2 1 0 1 2 4 0 1 0 1 2 3 2 0 1原创 2018-01-10 15:13:21 · 585 阅读 · 0 评论 -
最大子列和问题(JAVA)
最大子列和问题描述:给定N个整数的序列{A1,A2,A3,……,An},求解子列和中最大的值。这里我们给出{-2,11,-4,13,-5,-2}这样一个序列,正确的最大子列和为20该题是在数据结构与算法中经常用于分析时间复杂度的典型题目,以下将给出四种方法来求解一、三层循环——穷举法(时间复杂度O(N^3)) 这种方法的思路就是将每一个子列和都求出来,然后找出最大子列原创 2017-10-28 18:27:01 · 2001 阅读 · 1 评论 -
查找算法——折半查找(JAVA)
折半查找问题描述:给定一个整数X和整数A0,A1,A2……A(n-1),后者已经预先排序并在内存中,求下标i使得Ai = X ,如果X不在数据中,则返回i = -1。我们首先可以想到的一种方法就是从左到右遍历,逐个匹配,运行花费线性时间。然而,这样的算法并没有考虑到题目中已经排序的这个事实,所以这种算法不能算是最优解。那么这里就引入了我们的折半查找,每次验证X是否是居中元素,如果是,即原创 2017-11-09 18:18:22 · 655 阅读 · 0 评论 -
高效幂运算(JAVA)--拆分解法、二进制解法
高效幂运算问题描述:假设有一机器能够存储这样一些大整数(或有一个编译程序能够模拟它),求一个相对大的数字(一般为400位左右)的极大幂(400位左右)显然我们可以使用Java内置函数pow()求解,但是这大概会需要进行10^400次乘法,而下面这种方法在最坏的情形下只需要大约2600次乘法拆分解法public class Pow { public static void原创 2017-11-09 20:47:46 · 2516 阅读 · 0 评论 -
动态规划之背包问题(JAVA)
背包问题之前的C语言版本已经将思路解析的差不多,虽然还有些许错误需要改正,但大体思路是正确的,需要的读者请参阅动态规划之背包问题(C语言) 背包问题本身就是典型的动态规划问题,所以这里只给出动态规划的算法。0-1背包思路一:常规做法import java.util.Scanner;public class Main { static Scanner in = new原创 2017-12-18 21:59:26 · 1024 阅读 · 0 评论 -
斐波那契数列(一)--对比递归与动态规划(JAVA)
兔子繁殖问题: 这是一个有趣的古典数学问题,著名意大利数学家Fibonacci曾提出一个问题:有一对小兔子,从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。按此规律,假设没有兔子死亡,第一个月有一对刚出生的小兔子,问第n个月有多少对兔子?相信上面的题目稍微有点经验的程序员都了解过,这就是著名的斐波那契数列(Fibonacci sequence),该数列,又称黄金原创 2017-12-19 21:30:46 · 2153 阅读 · 0 评论 -
排序算法(一)--桶排序、冒泡、快排(JAVA)
排序算法汇总参考书籍–《啊哈!算法》 作者:啊哈磊首先提出一个问题:班内有5名同学,成绩分别为5,8,2,4,2分(满分10分),需要将成绩从小到大排序简化版 桶排序 时间复杂度O(N)import java.util.Scanner;public class Bucket_sort { public static void main(String[] args)原创 2018-01-07 16:40:09 · 249 阅读 · 0 评论 -
Java集合类及常用数据结构
下面这个图示为JAVA的集合类关系图,没用用严格的UML,了解其中的关系即可,其中颜色强调的几个类为常用的集合类。原创 2018-01-07 18:54:00 · 700 阅读 · 0 评论 -
搜索算法(一)--DFS/BFS求解拯救同伴问题(JAVA)
拯救同伴问题问题描述:假设有如下迷宫,求解从某一点出发到目标位置的最短距离Input: 5 4 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 1 1 4 3Output: 7深度优先搜索(DFS)import java.util.Scanner;public class DFS { static int[原创 2018-01-07 20:14:23 · 243 阅读 · 0 评论 -
搜索算法(二)--DFS/BFS求解炸弹人问题(JAVA )
炸弹人问题问题描述:小人可以在迷宫中任意地方放置一个炸弹,炸弹可以在以该点为中心的十字方向杀死怪物,但是触碰到墙之后不再能传递攻击。求将一个炸弹放在哪个位置可以杀死更多的怪物??Input: 13 13##############GG.GGG#GGG.####.#G#G#G#G##.......#..G##G#.###.#G#G##GG.GGG.#.GG##G#原创 2018-01-10 12:45:32 · 796 阅读 · 0 评论 -
搜素算法(基础)--DFS/BFS算法(JAVA)
DFS、BFS的定义及C语言算法实现请参照 连通图遍历策略之深度优先搜索(C语言) 连通图遍历策略之广度优先搜索(C语言)为了便于理解这里的数据是一个无向图,要求输出遍历顺序下面只给出用例和算法,之后可以根据后面的三个题目进行深入学习 Input: 5 5 1 2 1 3 1 5 2 4 3 5 Output: 1 2 4 3 5 DFSimport ja原创 2018-01-10 19:37:26 · 966 阅读 · 0 评论 -
图论算法(一)--最短路径的DFS/BFS解法(JAVA )
最短路径–城市路径问题:问题描述:求从1号城市到5号城市的最短路径长度 Input: 5 8 1 2 2 1 5 10 2 3 3 2 5 7 3 1 4 3 4 4 4 5 5 5 3 3 Output: 9DFSimport java.util.Scanner;public class minPath { static原创 2018-01-11 10:03:03 · 5719 阅读 · 4 评论 -
图论算法(二)-最短路径的Dijkstra [ 单源 ] 和Floyd[ 多源 ] 解法(JAVA )
一、Dijkstra算法问题描述:求一个点到任意个点的距离 思路:单源最短路径问题,使用Dijkstra算法 Input: 6 9 1 2 1 1 3 12 2 3 9 2 4 3 3 5 5 4 3 4 4 5 13 4 6 15 5 6 4Output: 0 1 8 4 13 17import java.util.Scanner;...原创 2018-01-11 17:53:38 · 1847 阅读 · 0 评论 -
图论算法(三)--最短路径 的Bellman-Flod [ 带负权值图 ] 的解法(JAVA )
Bellman-Flod算法对于带有负权值的图,我们已经不能通过Dijkstra算法进行求解了 原因:Dijkstra每次都会找一个距源点(设为s)最近的点,然后将该距离定为这个点到源点的最短路径;如果一个顶点u被加入了book[i])( book[i] == 1 说明这个s到u的路径权值已被记录,不可再更改),但是如果存在v到u的权值为负,那么s经v到u到值要更小。 例如: 如果用原创 2018-01-11 20:41:17 · 1644 阅读 · 1 评论