
数据结构与算法
文章平均质量分 90
ifenghao
用数据感知世界
展开
-
Kendall tau距离:求两个排列之间的逆序数
Kendall tau距离的定义以下定义取自wiki百科Kendall tau distance: The Kendall tau rank distance is a metric that counts the number of pairwise disagreements between two ranking lists. The larger the distance, the m原创 2015-11-02 23:49:06 · 9274 阅读 · 2 评论 -
机器人走方格
题目有一个X×YX\times Y的网格,一个机器人只能走格点且只能向右或向下走,要从左上角走到右下角。请设计一个算法,计算机器人有多少种走法。给定两个正整数x,y,请返回机器人的走法数目。测试输入: 2 2测试输出: 2分析1使用动态规划求解,定义n[i,j]n[i,j]为从起点[0,0][0,0]到点[i,j][i,j]的走法数目,则递归式为n[i,j]={1,n[i−1,j]+n[i原创 2017-04-11 17:38:13 · 712 阅读 · 0 评论 -
动态规划求最长回文子序列
要求找出字符串中最长回文子序列,可以在原字符串中不连续。如“character”的最长回文子序列为“carac”。分析1设字符串ss从第ii个字符到第jj个字符的最长回文子序列长度为p[i,j]p[i,j],则递归式为p[i,j]=⎧⎩⎨⎪⎪1,p[i+1,j−1]+2,max(p[i+1,j],p[i,j−1]),i=ji≠j,si=sji≠j,si≠sjp[i,j]=\left\{\beg原创 2017-04-09 00:33:16 · 1022 阅读 · 1 评论 -
最大距离二叉树节点
题目给定一个二叉树,定义两个节点的距离为这两个节点之间所有边的个数,要求这个二叉树中两个节点之间的最大距离。例如下图,两个节点之间的最大距离是5。分析1对于树中任何一个节点,包括该节点的树及其所有子树中存在的最大距离可以通过三种途径得到:在该节点的左子树中;在该节点的右子树中;将该节点作为根,横跨左右子树,最大距离是该节点左子树最大深度,加上右子树最大深度,再加2。这样很容易写出递归形式的实原创 2017-05-14 11:18:18 · 937 阅读 · 0 评论 -
最近二维点对
题目给定二维坐标系中的nn个点,求其中最近的点对。测试输入 5 1 2 -2 3 2 -1 0 3 -3 0测试输出 1.414分析1如果将点的距离两两计算出来需要O(n2)O(n^2)的时间复杂度,显然不是最优方案。先考虑一维数组情况,如果数组已经排好序,则只需要再遍历一遍,找到相邻值的最小距离即可,时间复杂度只是O(nlog(n))O(nlog(n)),但是这种方法不能推广到原创 2017-04-27 23:50:14 · 3708 阅读 · 1 评论 -
最大和连续子数组
题目对于一个整数数组,求其连续子数组的最大和。测试输入 7 -2 5 3 -6 4 -8 6测试输出 8分析可以从后向前考虑问题。数组array[i]array[i],i=0∼n−1i=0\sim n-1,定义total[i]total[i]表示前ii个元素中连续子数组的最大和,如果子数组不以array[i]array[i]结尾,则total[i]=total[i−1]total[i]=原创 2017-04-23 20:03:07 · 631 阅读 · 0 评论 -
最长递增子序列
题目求一个数组中最长递增子序列,要求时间复杂度尽量低。测试输入 7 2 1 4 3 1 5 6测试输出 4分析1采取从后向前的分析思路。如果已知第ii个元素存在于最长递增子序列中,那么前ii个元素的最长递增子序列的问题可以转化为,在前i−1i-1个元素中所构成的最长递增子序列,加上这个第ii个元素。由此可见子问题具有独立性,可以使用动态规划来完成。数组array[i]array[i],i原创 2017-04-23 17:12:59 · 517 阅读 · 0 评论 -
数字和方法数
题目给定一个有nn个正整数的数组arrayarray和一个整数sumsum,求选择数组arrayarray中部分数字和为sumsum的方案数。当两种选取方案有一个数字的下标不一样,我们就认为是不同的组成方案。 输入为两行,第一行为两个正整数nn(1 ≤ nn ≤ 1000),sumsum(1 ≤ sumsum ≤ 1000),第二行为nn个正整数(32位整数),以空格隔开。测试输入 5 15原创 2017-04-25 15:28:57 · 1547 阅读 · 0 评论 -
广度优先搜索:迷宫最少步数
题目对于一个10*10的迷宫,入口在第一行第二列,出口在最后一行第九列。迷宫中“#”代表墙,“.”代表通路,从任意一个“.”点只能一步走到上下左右四个方向的“.”点。求出走出迷宫所需要的最少步数。测试输入 #.######## #........# #........# #........# #........# #........# #........# #........#原创 2017-04-24 00:17:38 · 1749 阅读 · 0 评论 -
深度优先搜索:能否走出迷宫
题目一个m×nm\times n的迷宫里有很多激光,用其起点和终点坐标(x1,y1,x2,y2)(x_1,y_1,x_2,y_2)来表示。有激光的地方不能通过。当起点为(0,0)(0,0),终点为(m,n)(m,n),且移动只能为上下左右各一个单位,问能否从起点到达终点。输入包括mm和nn,接着是激光的个数,每个激光的使用4个坐标表示。如果能够走出迷宫输出1,否则输出0。测试输入 100 80原创 2017-04-27 14:50:34 · 1032 阅读 · 0 评论 -
数论之模加法运算
问题一个mm位的整数,有多少可以被整数nn整除?其中mm可以大于20。测试输入 1 3测试输出 4分析1这个问题显然不能穷举所有的情况。数论中的模加法运算有这样的性质(对乘法也是一样):(a+b) mod n===(a mod n+b mod n) mod n(a mod n+b) mod n(a+b mod n) mod n\begin{array}{lcl}(a+b)\ \text原创 2017-04-12 21:16:10 · 15277 阅读 · 3 评论 -
回溯法求八皇后问题
题目在n×nn\times n棋盘上放置nn个皇后,使她们互不冲突,需要每个皇后不能在同行、同列或者同对角线,求所有解。分析经典回溯法求解例题。定义cols[i]cols[i]表示第ii行的皇后所放的列,则其长度为nn。逐行穷举皇后的位置,一旦发现某一行无论如何放置都会冲突则回溯到上一行,从上一行的下个位置继续穷举。由于是逐行穷举,所以不用考虑0∘0^\circ方向的冲突,只需要考虑90∘90^\c原创 2017-04-11 23:53:51 · 576 阅读 · 0 评论 -
利用双向队列构造链接式优先队列
优先队列的定义优先队列中的元素被赋予优先级。插入元素时保持优先队列部分有序,删除元素时具有最高优先级的元素最先删除。优先队列分为面向最高优先级的优先队列和面向最低优先级的优先队列。数据结构二叉堆当一棵二叉树的每个结点都大于等于它的两个子结点时,这个二叉树称为堆有序,也被称作二叉堆。一般二叉堆都是一棵完全二叉树,如图所示: 基于二叉堆的优先队列二叉堆可以很好的实现优先队列的基本操作:插入元素和原创 2015-10-24 12:21:19 · 1563 阅读 · 0 评论 -
利用队列构造链接式完全二叉树
完全二叉树的定义若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。数组式完全二叉树将二叉树的节点按照层级顺序放入一个数组,就构建了一个数组式完全二叉树。根节点位于0,它的子节点位于1、2,子节点的子节点位于3、4、5、6,等等。这种构建方式非常简单,使用非常广泛,但是由于数组占用的是连续的内存,其大原创 2015-10-23 13:32:25 · 2011 阅读 · 0 评论 -
非递归快速排序
快速排序常常使用递归算法来实现,其运行时只使用lgN 的系统调用栈。如果想更清楚快速排序的运行过程,我们可以使用非递归的方法来实现快速排序。其方法最重要的部分是显式的使用一个栈来保存切分数组的下标,使用一个循环将出栈的子数组切分为二,并将结果重新入栈(这两个切分结果的入栈顺序不影响最后结果),直到结果都成为长度为一的子数组,此时排序完毕。 代码如下:// 非递归快速排序public class原创 2015-10-18 20:12:49 · 1010 阅读 · 0 评论 -
单链表的归并排序
归并排序是分治算法思想的一个具体体现。利用分治算法进行排序时,可以从两个方面进行考虑:merge方法:将两个已经有序的小集合合并为一个有序的大集合;sort方法:利用递归的方法,将总集合逐次二分为只有单个元素的集合,然后用merge方法将集合逐次两两合并,最后达到将总集合排序的目的。对于链表而言,由于不能像数组一样随机访问,故而使用一般方法会因为迭代寻找节点而消耗大量的时间。归并排序可以说是链原创 2015-10-15 23:59:58 · 1000 阅读 · 0 评论 -
将中序表达式转为后序表达式
中序表达式:操作运算符在中间,被操作数在操作运算符的两侧的表达式。一般书面上的表达式大多数都是中序表达式,人们看起来直观易懂。 后序表达式:要求操作符出现在其操作数之后。后序表达式易于计算机处理,因为表达式中可以没有括号,而且只需要单向扫描,不再需要考虑运算符的优先级。 举例: 中序表达式: 2*3/(2-1)+3 *(4-1) 后序表达式: 2321-/* 341- *原创 2015-10-02 21:17:38 · 2487 阅读 · 0 评论 -
使用堆栈将缺少左括号的表达式补全并计算其值
问题描述:输入一个缺少左括号的表达式,打印出其补全括号的中序表达式,并计算表达式的值。例如给定表达式: 1+2)*3-4)*5-6)))得到输出: ((1+2)((3-4)(5-6)))计算得到其值为3 问题分析:计算表达式的问题通常使用堆栈。有的算法中利用操作符的优先级以及复杂的记录过程,其实只要利用好堆栈的特性,任何多余的操作都是完全没有必要的。这里首先考虑计算出表达式的值的问题,原创 2015-10-02 17:32:24 · 1163 阅读 · 2 评论 -
快速切分法寻找中位数的递归与非递归实现
中位数对于有限的数集,可以通过把所有观察值高低排序后找出正中间的一个作为中位数。如果观察值有偶数个,则中位数不唯一,通常取最中间的两个数值的平均数作为中位数。中位数寻找的快速算法一般寻找中位数可以先将数组排序,按照次序将中间的数据作为中位数即可,其时间复杂度主要取决于排序算法的时间复杂度,利用快速排序可以将其控制为线性对数量级。 但是能否打破线性对数的限制呢?其中最关键的问题是,寻找中位数并原创 2015-11-01 21:31:26 · 6608 阅读 · 0 评论 -
堆砌相同高度的塔
题目小易有n块砖块,每一块砖块有一个高度。小易希望利用这些砖块堆砌两座相同高度的塔。为了让问题简单,砖块堆砌就是简单的高度相加,某一块砖只能使用在一座塔中一次。小易现在让能够堆砌出来的两座塔的高度尽量高,小易能否完成呢。输入描述: 输入包括两行:第一行为整数n(1 ≤ n ≤ 50),即一共有n块砖块,第二行为n个整数,表示每一块砖块的高度height[i] (1 ≤ height[i] ≤ 5原创 2017-04-09 11:19:58 · 3350 阅读 · 4 评论 -
矩阵快速幂求斐波那契数列
快速幂求数aa的nn次幂,可以采用二分法进行快速计算,即an={an2⋅an2,a⋅an2⋅an2,n为偶数n为奇数a^n=\left\{\begin{array}{ll}a^{\frac{n}{2}}\cdot a^{\frac{n}{2}}, & n为偶数\\a\cdot a^{\frac{n}{2}}\cdot a^{\frac{n}{2}}, & n为奇数\end{array}\ri原创 2017-04-11 17:05:55 · 2817 阅读 · 1 评论 -
数组分割使子数组和接近
题目描述1:一个无序且长度为偶数的正整数数组,要求将它分割成为两个长度相等的子数组,且这两个子数组的和最接近。输入数组的长度和相应的元素,输出两个子数组各自元素之和。 描述2:两个长度相等的数组,要求将它们的元素互换,使得这两个数组的和最接近。测试输入 10 1 5 7 8 9 6 3 11 20 17测试输出 43 44错误分析设数组所有元素之和为sumsum,要让分割的两个子数组的原创 2017-05-12 21:53:14 · 5077 阅读 · 0 评论