![](https://img-blog.csdnimg.cn/20201014180756930.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
常用算法
文章平均质量分 75
l-jobs
莫道征途路漫漫,愿效江水去不还
展开
-
破碎的砝码问题
1.问题描述 一天商人不小心把40磅重的砝码摔成4部分,发现4部分砝码的重量都是整磅数,而且可以用它们称出任意1-40之间的整数磅质量,问这四块砝码各重多少磅?2.该问题的数学分析 ①必须有1磅的砝码,否则39磅的重量无法称出. ②有了1磅的砝码后,再加上一个3磅的砝码,可称出2~4磅的重量. ③有了1磅和3磅的砝码后,再加上一个9磅的砝码,可称出5~原创 2015-05-16 09:41:43 · 1688 阅读 · 0 评论 -
快速排序的优化
注:以下代码参考博客参考博客地址快速排序的期望时间复杂度为O(nlogn),最坏时间复杂度为O(n²)。为了避免出现最坏情况,我们可以对其进行改进。1.哨兵的改进,为了使每次划分的数不致于使两边相差过大,我们可以选择三者取中法选哨兵,即首尾和中间数的中位数来作为哨兵。2.小数据量的改进,递归的快速排序在大概n3.相同数字的改进,在存在大量相同数字的时候快速排序是很慢的,我们采用原创 2016-01-29 12:33:58 · 596 阅读 · 0 评论 -
交换排序
交换排序的核心思想是: 给定一组数据,两两比较待排序记录的关键字,发现两个记录的次序相反时即进行交换,直到没有反序的记录为止。 基于交换思想的排序方法有两种,冒泡排序和快速排序。冒泡排序 基于交换的思想其实比较符合人们的认知,冒泡排序就是依次比较两个关键字,如果发现两者的关系是逆序,就交换,第一次两两比较可以得出最大原创 2016-01-12 22:16:56 · 592 阅读 · 0 评论 -
求无序数组之中最小的k个数
在无序数组中国找最小的k个数,一般有以下几种办法: 1.比较排序,然后找最小的k个数,时间复杂度下界为O(nlogn) 2.计数排序,时间复杂度可以做到O(n),但是要看具体的数据情况。也比较费空间。以上做法都是把所有元素的个数排好序,但是我们只需要找到前k个最小的数,不要求所有数据有序。 3.遍历所有数据,找到最小的数。再遍历剩下的数,找第二小的数,如此遍历k次,时间复杂度原创 2016-01-29 15:56:57 · 1923 阅读 · 0 评论 -
插入排序
插入排序是一种经典的排序算法,其中心思想就是: 给定一组数据,划分为有序区和无序区,在无序区的元素选出一个插入到有序区,使之仍然有序,重复以上步骤,直到无序区不再有元素为止。直接插入排序 一开始我们认为一个元素就是有序的,直接插入排序就是认为第一个元素有序,然后从第二个元素开始比较,插入到前面,共需比较n-1次,第n次移动的最多次数是n次,总共的移动次原创 2016-01-12 19:49:26 · 555 阅读 · 0 评论 -
bfprt算法求最小的k个数
bfprt算法是一种经典的线性时间内求最小的第k个数或者最小的k个数的算法。比如我们要知道销量是前几名商品或者是浏览量最多的前几个网站,我们不需要排序,利用bfprt算法就可以完成。bfprt算法又称快速选择算法,其思想是利用快速排序的划分来确定位置。此算法经典而优雅,值得我们学习。步骤 1.将输入的元素划分为5个元素一组,至多有一组不足5个元素。原创 2016-01-30 11:59:27 · 985 阅读 · 0 评论 -
选择排序
选择排序的核心思想是: 给定一组数据,选出最小(大)的放在合适位置上,然后在剩下的数据中选择最小(大)的不放在合适位置,不断重复这个过程,直到所有的数据都有序。简单选择排序 简单选择排序的操作为:通过n-i次关键字间的比较,从n-i+1个记录中选择关键字最小的记录,并和第i(1。总的比较次数为n(n-1)/2,时间复杂度是o(n^2),原地排序,原创 2016-01-13 11:32:20 · 389 阅读 · 0 评论 -
归并排序
归并排序是一种利用分治思想来排序的算法。其核心思想是 不断合并有序数据,直到所有数据有序为止。 这里介绍二路归并,即初始有序长度为1,然后两两归并,如果重复,直到所有元素有序。 二路归并的递归算法比较简洁,但是实用性很差。因为它调用了递归栈,需要额外的空间log2n次,再加上需要与数据等长度的额外数组,所以空间复杂度是o(n),归并算法的时间复杂度是原创 2016-01-13 14:13:56 · 345 阅读 · 0 评论 -
递归式求解的三种方法
算法设计经常用到递归,而递归式是比较好写的,也是容易反应算法的设计思路的,我们分析含递归算法的时间复杂度就要求解递归式。下面介绍求解递归式的三种方法,以下方法参考《算法导论》,图片来自网络。1.主方法求解递归式 一种求解大部分递归式的公式。简洁实用,有兴趣的同学可以自己去看算法导论上的证明,这里只列举结论。 给出递归式: T(n) = a * T(n/b) + f(n)原创 2016-02-01 09:34:59 · 29937 阅读 · 2 评论 -
直线段的扫描转换算法
如何在离散的像素点上画出一条连续的直线,这是直线段的扫描转换算法要研究的内容。以下画线的代码都只针对斜率在0到1之间的时候的线段。其余斜率的直线画法可以以此类推。数值微分法 简单的来说,就是每次画点的时候,x增加1个像素,y增加k(斜率)个像素,然后对y的值进行取整,如果k>1,x,y互换。//该算法仅仅适用于|k|<=1,传递参数时,必须x0<=x1 void DDA原创 2016-10-10 13:31:51 · 1749 阅读 · 0 评论 -
判断字符串中有无相同字符
题目描述请实现一个算法,确定一个字符串的所有字符是否全都不同。这里我们要求不允许使用额外的存储结构。给定一个string iniString,请返回一个bool值,True代表所有字符全都不同,False代表存在相同的字符。保证字符串中的字符为ASCII字符。字符串的长度小于等于3000。测试样例:"aeiou"返回:True"BarackObama"返回原创 2016-03-19 14:01:43 · 1297 阅读 · 0 评论 -
卡特兰数及其应用
一道栈的题目最近做一道有关栈的题目,题目是这样的: 若一序列进栈顺序为e1,e2,e3,e4,e5,问存在多少种可能的出栈序列? 这道题用递推可以算出来,假设第k个数进栈,设f(k)表示k个数的总出栈序列数,则它前面的k-1个数有f(k-1)种出栈序列,它后面有f(5-k)种出栈序列,由乘法原理,这时有f(k-1)*f(5-k)种。由于k取不同值的情况是相互独立原创 2015-12-20 13:12:58 · 2307 阅读 · 0 评论 -
最长公共子序列问题(动态规划求解)
问题 求长为m的序列和长为n的序列的最长公共子序列(可以不连续),如ABCBDAB和BDCABA,BCAB和BCBA都是它们的最长公共子序列。在生物学上用来求DNA序列的匹配度。这里我们用它来举例学习动态规划方法。先放结论: 动态规划是暴力递归的一种优化。要写出动态规划,首先要写出递归式,然后试着找出最优子结构与重叠子问题。1.最优子结构就是一个问题的最优解原创 2016-02-08 10:45:48 · 7840 阅读 · 0 评论 -
两个有关“基”的数学趣题
这周遇到了两个有趣的数学问题,觉得它们有一些比较相似的性质。所以在这里总结一下。后面会补充和修正。这里写出来,纯做启发。1.十进制的基这里的基是指一组量,这些量可以线性组合的表示出任何这个维度的量。十进制的一组基就是一组十进制数,这组十进制数可以线性表示出任何十进制数。并且这种表示是唯一的。线性表示,可以理解成相加运算。十进制的一组基,即1,2,4,8,16,32,64原创 2015-12-05 18:22:37 · 684 阅读 · 0 评论 -
堆排序的初步学习
注:以下堆排序的代码借鉴了博客http://blog.csdn.net/morewindows/article/details/6709644/这个排序算法的时间复杂度为O(nlogn),主要是花费在建堆和调整堆上。所以对记录数较少的文件并不值得提倡,但是由于它的最坏时间复杂度是O(nlogn),所以对于记录数较多的文件是比较有效的。堆的概念介绍完全二叉树如果满足每一个父节原创 2016-01-01 11:19:33 · 484 阅读 · 0 评论 -
用穷举法列出24点的解
大家都玩过24点的游戏吧,这里介绍一种24点游戏的解法,用穷举法来搜索出24点的所有解。1.游戏规则 .给定4个1-9的整数,对它们进行四则运算,寻找能得到24点的表达式,注意数的位置不能改变。2.题目分析 4个整数进行四则运算有4*4*4 = 64种可能的解,把运算规则全穷举出来实际上并不复杂,关键是如何穷举。我们可以用3个整形变量来表示运算原创 2015-05-14 22:59:05 · 1863 阅读 · 0 评论 -
从八皇后问题体会回溯法
1.从八皇后问题说起 国际象棋里有个很厉害的棋子叫皇后,她可以横竖斜八个方向吃子,八皇后问题就是研究如何在一个8*8格子里摆放8个皇后,要求排列出所有可能的解。进一步可推出n皇后问题,即在n*n格子中放置n个皇后的解法。2.解决八皇后问题的一种常用方法(纯概念预警) 回溯法,一种类似枚举的搜索试错过程。找出解空间,一般用节点树或图来表示,从根节点开始原创 2015-05-12 21:14:16 · 1234 阅读 · 0 评论 -
几个小算法
1.递归求组合数////////////////////用递归求出组合数比用for省时,关键在于组合数公式C(n, m) = C(n-1, m-1)+C(n, m-1)C语言代码如下:# include int combination(int m, int n){ if (n==0 || n==m) return原创 2015-06-06 17:03:53 · 579 阅读 · 0 评论 -
求已知字符串的最大回文字符串长度,并输出该字符串
求已知字符串的最大回文字符串长度,并输出该字符串(不考虑数字)输入示例: Madam,I'm Adam.输出示例: Madam,I'm Adam.题目分析:输入分析:C语言的常用输入字符串函数scanf(),gets()都不适合本题,scanf()会有输入不了空格的麻烦,gets会出现缓存区溢出漏洞,已经被废弃(vs2012代替的是get_s(),但原创 2015-10-24 15:56:45 · 1851 阅读 · 0 评论 -
海盗问题和汉诺塔问题的分析
海盗分金币问题:有100个金币和5名海盗,现在由5号海盗先分金币,假如它提出的方案有超过一半的海盗反对,就会被杀掉,换第4号海盗分,直到1号海盗为止。问5号海盗应该如何分配金币才能使自己利益最大化。(假设每个海盗都是理性的)答案:给3号和1号海盗各分一枚金币,自己分99枚。分析:我们反向分析,如果只有两名海盗1号和2号,那么由2号分金币的话1号1枚金币都得不到。所以3号只需原创 2015-11-21 17:24:48 · 636 阅读 · 0 评论 -
子数组的最大累加和问题
这周看到了一道经典的算法题,和大家分享一下。题目:给定一个数组arr,返回子数组的最大累加和。例如,arr=[1,-2,3,5,-2,6,-1],所有的子数组中,[3,5,-2,6]可以累加出最大的和12,所以返回12。这道题其实是可以dp的。我们最笨的办法是穷举出它的所有连续子数组之和,然后比较出最大的那个。可以看出,在连续穷举的过程中重复了很多计算。既然它是连续的一原创 2015-12-12 19:58:37 · 462 阅读 · 0 评论 -
子矩阵的最大累加和问题
下面这个问题是数组的最大累加和问题的拓展题目:给定一个矩阵matrix,其中的值有正、有负、有0,返回子矩阵的最大累加和。 例如,矩阵matrix为:-90 48 78 64 -40 64-81 -7 66其中,最大累加和的子矩阵为: 48 78-40 64-7 66所以返回累加和209。再例如,matrix为:-1 -1 -1原创 2015-12-12 20:06:12 · 655 阅读 · 0 评论 -
求多项式相加的迭代算法
问题描述:假设有n+2个实数a0,a1,…,an,和x的序列,要对多项式Pn(x)= anxn +an-1xn-1+…+a1x+a0 求值,直接方法是对每一项分别求值,并把每一项求的值累加起来,这种方法十分低效,它需要进行n+(n-1)+…+1=n(n+1)/2次乘法运算和n次加法运算。 通过如下变换我们可以得到另一种算法,即Pn(x)= anxn原创 2016-01-16 10:36:45 · 2307 阅读 · 0 评论 -
求连续子数组的最大和
问题描述:给定一个n个元素的整型数组,求出最大的连续子数组的始末位置与最大连续子数组的和。问题分析: 这个问题在网上有很多资料可以参考,可惜大部分资料是不完善或者有错误的,在《算法导论》里面这个问题是用来介绍分治算法的,但是这道题作为常考的面试题,从里面可以学到的东西还是很多的,所以在这里学习一下,有什么问题请多指正。首先我们应该考虑的是边界条件和特殊情况:1.如果原创 2016-01-17 14:11:17 · 475 阅读 · 0 评论 -
初步了解K sum问题
问题描述: 给定一组数字a[N], 一个常数(比如 int target) ,要求在这一堆数里面找到K个数字,使得这K个数字的和等于target。 注意这一组数字可能有重复项:比如 1 1 2 3 , 求3sum, 然后 target = 6, 你搜的时候可能会得到 两组1 2 3, 1 2 3,1 来自第一个1或者第二个1, 但是结果其实只有一组,所以最后结果要去重。原创 2015-12-31 11:30:37 · 907 阅读 · 0 评论 -
非比较排序
基于比较的排序时间复杂度下界以下内容参考自《算法导论》基于比较的排序算法可以用一颗完全二叉树(决策树)来表示,节点表示每一次的比较过程,叶子节点表示最终的排序顺序,叶子节点一共有n!个(n表示数据个数,一共有n!种排列方式)二叉树的高度h就是比较的次数,由二叉树的性质,叶子节点的个数不大于2^h,所以有2^h>=n!;2^h>=n! = n*(n-1)*(n-2)*...*原创 2016-01-18 20:43:28 · 976 阅读 · 0 评论 -
Base64编码
一. Base64编码由来 为什么会有Base64编码呢?因为有些网络传送渠道并不支持所有的字节,例如传统的邮件只支持可见字符的传送,像ASCII码的控制字符就 不能通过邮件传送。这样用途就受到了很大的限制,比如图片二进制流的每个字节不可能全部是可见字符,所以就传送不了。最好的方法就是在不改变传统协议的情 况下,做一种扩展方案来支持二进制文件的传送。把不可打印的字符也能用可打印字符来表示,问...原创 2018-09-29 11:23:50 · 295 阅读 · 1 评论