数据结构算法学习
文章平均质量分 66
djd已经存在
······
展开
-
python实现大整数相乘---格子乘法
以前做ACM的时候,许多人都通过 BigInteger 来实现大数乘法,让我记忆犹新的事2012年的辽宁省赛在大连大学,第一道水题就是大整数乘法,那时还不会java。 大数乘法的实现是基于印度的格子乘法,使用这种方法,计算 m 位数乘以 n 位数只需要创建一个 m+n 位的数组保存结果即可。今天我们来用python来模拟一下格子算法的运算过程,python来写算法还是很简单的。下面是从维基原创 2015-05-11 21:35:42 · 7171 阅读 · 0 评论 -
快速排序c++和python对比分析
C++的快速排序基本思想就是,任意取出一位作为对比位x,分别从序列两端开始探测,先从右边到左找到一个比x大的数,在从左边到右找到一个比x小的数,然后交换他们,一直循环到i=j。这一次交换完毕之后,将x换到中间位置,因为左边都比它小,右边都比它大,所以它在中间。在函数最后,有一个递归函数,分别在对左边和右边进行刚才的排序,直到将元素分解到1个的时候停止,循环结束。void quicksort(i原创 2015-05-04 20:13:25 · 1329 阅读 · 0 评论 -
python实现二分查找及bisect模块的简介
在查找方面,python中有list.index()的方法。>>> a=[2,4,1,9,3] #list可以是无序,也可以是有序>>> a.index(4) #找到后返回该值在list中的位置1这是python中基本的查找方法,虽然简单,但是,如果由于其时间复杂度为O(n),对于大规模的查询恐怕是不足以胜任的。二分查找就是一种替代方法。原创 2015-05-12 22:57:58 · 5969 阅读 · 0 评论 -
python实现ZOJ1745(简单模拟)
我就直接贴代码了,代码上有具体的思路。# -*- coding:utf-8 -*-'''每一行输入最少两个数最多21个数,且最后一步一定要到达饼干。每一行输入的第一个数是饼干所在的位置,且饼干的位置不能为0.输出有三种状态,输出什么状态,取决于这一次和上一次距离饼干的距离是否近了还是远了还是相同近了返回warmer远了返回colder如果相同则返回same如果输入的数字与饼干所在位原创 2015-05-13 00:14:05 · 1355 阅读 · 0 评论 -
二叉树查找之python实现--(插入)
借维基百科的话来说就是二叉树就是一种每个节点最多有两个子树的树结构。但是今天讨论的是二叉查找树,这个查找树就是二叉树的一种延伸吧,加了几条限制就变成了二叉查找树。下面我们来看看二叉查找树有什么性质呢,如果左子树不为空,那么一定全部小于等于根节点,同样右子树也是一样的,而且左右子树都是二叉查找树。最后树中没有键值相同的节点。如果满足上述四条性质的二叉树就是二叉查找树。下面我们来一张二叉查找树的图原创 2015-05-13 23:35:32 · 5005 阅读 · 1 评论 -
归并排序详细解析
我们先来一个两个有序的数组a和b进行排序的代码,两个有序的数组进行排序只需每次选择两个数组中最小的那个数放进c中就ok了,之后如果那个数组还有剩余就将其直接接在c后面。时间效率还是很快的达到了O(n)。python源码def MemeryArray(a,b,c): i = 0 j = 0 k = 0 n = len(a) m = len(b)原创 2015-05-25 23:29:22 · 1198 阅读 · 0 评论 -
DFS解八皇后问题
仔细思考深度优先搜索其实可以分为大概四步.1.发现,找到想要找的节点,如八皇后就是找到当前行放置皇后的那个点,马走日就是下一步的落点.2.递进,如果不满足结束条件就继续递归,进入下一层.如八皇后问题就是进入下一行.3.满足,条件满足了之后,就输出结果,一般都是用一个全局变量来控制数量,一旦==N,就输出结果.4.返回,dfs得回溯才能遍历所有的结果.问题描述八皇后问原创 2015-08-25 00:41:07 · 3661 阅读 · 1 评论 -
归并排序详细分析
首先我们可以先想象一下,将两个有序的数组A、B合并成一个数组C有什么好的办法。我们只需从两个数组的第一位开始比较就可以了,但是到最后一定会有一个数组会剩下一些元素,我们只需将其全部连接到C后面就可以了,这样是不是很简单,而且时间效率也达到了O(n)。//将有序数组a[]和b[]合并到c[]中void MemeryArray(int a[], int n, int b[], int m, in原创 2015-07-29 23:53:51 · 1277 阅读 · 0 评论 -
DFS解马走日问题
问题描述在n*n的棋盘中,马只能走"日"字。马从位置(0,0)出发,把棋盘的每一格都走一次且只走一次。找出所有路径。 5*5的棋盘上,有304种解。问题分析搜索过程是从(0,0)出发,按照深度优先的原则,从8个方向中尝试一个可以走的点,直到尝试过所有的方向,走完棋盘上的所有点,得出所有的解。马走日问题可以看成是在层数为n*n的8叉树中,找出所有的解。#i原创 2015-08-25 01:10:43 · 2985 阅读 · 0 评论 -
如何产生1-100 之间的100个不重复的随机数
1:首先从原始数组中随机选择一个数字,然后将该数字从数组中剔除,再随记选,再剔除,重复99次,就解决了。 我们知道从数组中剔除一个元素的复杂度为O(N),那么随机选取n个数字,它的复杂度就是O(N2)了。 2:用hash作为中间过滤层,因为在数组中,我们采用随机数的话,也许随机数在多次随机中可能会有重复,所以需要用hash来判断一下, 如果在hash中重复,则继续产生随原创 2015-07-18 19:39:04 · 6526 阅读 · 0 评论 -
Farey序列(Stern-Brocot tree的衍生)
早在一百多的年前,人们就发现了Farey序列,它是介于0和1之间满足一定的性质的一个有理数列。但一直到近代才被得到真正的应用,特别是在近代数论中,也逐渐受到人们的重视。这里对于这个序列的性质进行了初步探讨研究,并根据这个性质得到关于有理数和无理数一些有趣的命题。网上找到的一段描述,学习一下。Farey序列Fn = {a/b | gcd(a,b)=1 && 0即由小于原创 2015-08-26 16:55:45 · 4357 阅读 · 1 评论 -
Stern-Brocot树 (生成0-1之间的所有真分数)
问题描述 [1] :给定输入N,输出0到1之间分母小于或等于N的真分数,并递增输出。比如说,N = 5时输出: 0/1 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 1/1解决方案 [2] :这个问题有个很漂亮的解决方法,称为Stern-Brocot树,取这个名字是因为这是由德国数学家Moritz Stern和法国的修理钟表商Achille原创 2015-08-26 16:48:06 · 5875 阅读 · 0 评论 -
BFS和DFS的简要分析
广度优先搜索(BFS),可以被形象的描述为“浅尝辄止”,具体一点就是每个顶点只访问它的邻接节点(如果它的邻接节点没有被访问)并且记录这个邻接节点,当访问完它的邻接节点之后就结束这个顶点的访问。广度优先用到了“先进先出”队列,通过这个队列来存储第一次发现的节点,以便下一次的处理;而对于再次发现的节点,我们不予理会——不放入队列,因为再次发现的节点:无非是已经处理完的了;或者是存储在队原创 2015-08-26 00:35:00 · 2470 阅读 · 0 评论 -
数据结构:胜者树与败者树
假设有k个称为顺串的有序序列,我们希望将他们归并到一个单独的有序序列中。每一个顺串包含一些记录,并且这些记录按照键值的大小,以非递减的顺序排列。令n为k个顺串中的所有记录的总数。并归的任务可以通过反复输出k个顺串中键值最小的记录来完成。键值最小的记录的选择有k种可能,它可能是任意有一个顺串中的第1个记录。并归k个顺串的最直接的办法就是进行k-1次比较确定下一个输出的记录。对k>2,我们可以通过使用转载 2015-08-26 17:20:23 · 1241 阅读 · 0 评论 -
最快排序之"桶排序"
桶排序的基本思想就是利用空间换时间,如果将一最大值为100000的一组数进行排序,最简单粗暴的方法就是桶排序,创建一个100001这么大的数组,每一位代表一个一个数,初始化时将数组全部赋值为零,一次读入需要排序的数,如果读入5278则将Num[5278]++;代表出现过一次5278。输入结束之后,从1开始遍历数组,如果不为0则输出,最后输出的就是一个有序的序列。这种思想在bit图也用到了,只是原创 2015-08-26 15:43:28 · 1927 阅读 · 0 评论 -
算法之枚举思想
一: 思想 有时我们解决某个问题时找不到一点规律,此时我们很迷茫,很痛苦,很蛋疼,突然我们灵光一现,发现候选答案的问题规模在百万之内,此时我们就想到了从候选答案中逐一比较,一直找到正确解为止。 二: 条件 前面也说了,枚举是我们在无奈之后的最后一击,那么使用枚举时我们应该尽量遵守下面的两个条件。 ① 地球人都不能给我找出此原创 2015-07-20 20:55:33 · 1530 阅读 · 0 评论 -
算法之分治思想
一、基本概念在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)……任何一个可以用计算机求解的问题所需的计算时间都与其规模有原创 2015-07-20 22:44:02 · 1365 阅读 · 0 评论 -
算法之贪心思想
这个贪心的行为在算法中也成为了一种指导思想,也就是说贪心算法所作出的选择在当时的环境下是最好的,说深一点就是它只是某种意义上的局部最优解,但不一定是全局最优解,此时往往接近于最优解。 一: 优点 前面也说了,贪心只是求的当前环境下的最优解,而不是追究整体的最优解,所以贪心就避免了为求的整体最优解而枚举各种方案所耗费的时间。 二: 问题原创 2015-07-20 20:48:59 · 1307 阅读 · 0 评论 -
算法之递推思想
一: 概念 通过已知条件,利用特定关系逐步递推,最终得到结果为止,核心就是不断的利用现有信息推导出新的东西。 二:分类 当然递推中有两种,“顺推”和“逆推“ 顺推:从条件推出结果。 逆推:从结果推出条件。三: 举例 顺推的例子 上过大学的应该都知道著名的“斐波那契”数列吧,说的是繁殖兔子的问题,题目我就大概说原创 2015-07-18 19:46:09 · 1443 阅读 · 0 评论 -
算法之递归思想
树的遍历的实现就是典型的递归思想。/** description:树的遍历示例,递归* 访问顺序:* 前序: 当前节点 - 左子树 - 右子树* 中序: 左子树 - 当前节点 - 右子树* 后序: 左子树 - 右子树 - 当前节点** write原创 2015-07-20 18:20:40 · 1251 阅读 · 0 评论 -
并查集简要分析
并查集:(union-find sets)一种简单的用途广泛的集合. 并查集是若干个不相交集合,能够实现较快的合并和判断元素所在集合的操作,应用很多,如其求无向图的连通分量个数等。最完美的应用当属:实现Kruskar算法求最小生成树。并查集的精髓(即它的三种操作,结合实现代码模板进行理解):1、MakeSet(x) 把每一个元素初始化为一个集合初始化后每一个元素的父亲节点是它本原创 2015-08-28 20:54:58 · 1308 阅读 · 0 评论 -
对动态规划(Dynamic Programming)的理解:从穷举开始
动态规划(Dynamic Programming,以下简称dp)是算法设计学习中的一道槛,适用范围广,但不易掌握。笔者也是一直不能很好地掌握dp的法门,于是这个寒假我系统地按着LRJ的《算法竞赛入门经典》来学习算法,对dp有了一个比过往都更系统\更深入的理解,并在这里写出来与大家分享。笔者着重描述的是从穷举到dp的算法演进,并从中获取dp解法的思路,并给出多种思考的角度,务求解决的是LRJ原创 2015-07-21 18:53:35 · 2164 阅读 · 0 评论 -
算法之回溯思想
1、概念 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。 许多复杂的原创 2015-07-21 12:51:19 · 1380 阅读 · 0 评论 -
算法之动态规划
一: 思想 首先要了解”动态规划“,必须先知道什么叫做”多阶段决策“,百科里面对这个问题解释的很全,我就load一段出来,大家得要好好品味,好好分析。 上面图中最后一句话就定义了动态规划是要干什么的问题。 二:使用规则 现在我们知道动态规划要解决啥问题了,那么什么情况下我们该使用动态规划呢? ① 最优化原理(最原创 2015-07-21 20:28:47 · 1218 阅读 · 0 评论 -
动态规划之最长公共子序列
今天看了一下动态规划的思想,基本最基本的问题就是背包、硬币、lcs。lcs在解决字符串相似度上比较常用,属于算法中的基础,我还没有掌握,自己得有多么多么水呀,但没关系今天之后你掌握了,你就向成功程序员向前走了一步。动态规划 既然是经典的题目肯定是有优化空间的,并且解题方式是有固定流程的,这里我们采用的是矩阵实现,也就是二维数组。第一步:先计算最长公共子序列的长度。原创 2015-07-21 16:17:25 · 1212 阅读 · 0 评论 -
算法之概率思想
一:思想 这里主要讲一下“数值概率算法”,该算法常用于解决数值计算问题,并且往往只能求得问题的近似解,同一个问题同样的概率算法求解两次可能得到的结果大不一样,不过没关系,这种“近似解”会随时间的增加而越接近问题的解。 二:特征 现实生活中,有很多问题我们其实都得不到正确答案,只能得到近似解,比如“抛硬币”求出正面向上的概率,”抛骰子“出现1原创 2015-07-21 21:42:52 · 1482 阅读 · 0 评论 -
并查集扩展之最小生成树Kruskal算法
并查集有很多经典的应用。在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。其中一个非常经典的应用是最小生成树的Kruskal算法。给定一个具有n个节点的连通图,它的生成树是原图的一个子图,包含所有n个节点,且有保持图连通的最少的边(n-1条边)。边权值最小的生成树是最小生成原创 2015-08-28 21:10:22 · 1554 阅读 · 0 评论 -
leetcode1 Two Sum题解
题目大概意思就是,我给你传进来一个vector容器和一个target,vector相当于一个数组,现在问target是有数组种哪两个数组成的,返回两个下标,注意函数的返回类型也是vector类型的,所以一定要注意. 题目刚到手的时候,发现这个与各大OJ套路不太一样啊,也就是与ACM不太一样,我还傻傻的调整输出格式什么的,而且这个是完善一个类的成员函数,而不是提交一个可以运行的完整原创 2015-08-30 15:20:47 · 1268 阅读 · 1 评论 -
STL之map、set数据结构基础
STL之map、set数据结构基础摘要:本文列出几个基本的STL map和STL set的问题,通过解答这些问题讲解了STL关联容器内部的数据结构,最后提出了关于UNIX/LINUX自带平衡二叉树库函数和map, set选择问题,并分析了map, set的优势之处。对于希望深入学习STL和希望了解STL map等关联容器底层数据结构的朋友来说,有一定的参考价值。转载 2015-08-30 15:52:31 · 1212 阅读 · 0 评论 -
算法之七大经典排序
针对现实中的排序问题,算法有七把利剑可以助你马道成功。 首先排序分为四种: 交换排序: 包括冒泡排序,快速排序。 选择排序: 包括直接选择排序,堆排序。 插入排序: 包括直接插入排序,希尔排序。 合并排序: 合并排序。冒泡排序简单来说就是利用两个for循环来进行排序,由前一个数据和后一个数据比较,如果前一个大于后一个则交原创 2015-07-23 10:11:29 · 1471 阅读 · 0 评论 -
动态规划入门教程之金矿的故事
----第一节----初识动态规划-------- 经典的01背包问题是这样的: 有一个包和n个物品,包的容量为m,每个物品都有各自的体积和价值,问当从这n个物品中选择多个物品放在包里而物品体积总数不超过包的容量m时,能够得到的最大价值是多少?[对于每个物品不可以取多次,最多只能取一次,之所以叫做01背包,0表示不取,1表示取] 为了用一原创 2015-07-23 13:18:52 · 1487 阅读 · 0 评论 -
leetcode2 Add Two Numbers题解
题的大概意思就是,输入两个列表,这两个列表是两个逆序的数,比如说1->2->4就代表421.然后将两个链表翻转后相加,存入列表中,同样按照逆序存入列表,将其返回,刚开始题意理解错了,WA了两次,题目给出的一组数据比较具有迷惑性,就是243+564与432+465的结果都是807,所以刚开始我以为输入的两个链表的数正序的,只需将结果翻转就可以了.其实这道题和大整数相加差不太多,只要考虑一下进位就没什原创 2015-08-30 22:46:44 · 1252 阅读 · 0 评论 -
最小生成树prim算法
普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小。借用维基百科的定义就是:从单一顶点开始,普里姆算法按照以下步骤逐步扩大树中所含顶点的数目,直到遍及连通图的所有顶点。输入:一个加权连通图,其中顶点集合为V,边集合为E;初始化:Vnew = {x原创 2015-08-29 20:51:42 · 1542 阅读 · 0 评论 -
堆排序详细分析(算法导论第六章)
本文将介绍另一种平均时间复杂度是O(nlogn)的排序方法——堆排序(Heap Sort)。堆排序使用了一种被称为“堆”的数据结构,这也是它相比其他两种排序方法的特殊之处。堆这种数据结构不仅可以用于排序,也可以用来维护优先级队列。本文最后还简要对比了快速排序和堆排序的优缺点。堆排序就是升级版的选择排序,选择排序基本就是两个for循环,内循环没循环一次确定列表中最小的元素,之后循环n次就原创 2015-07-23 16:50:20 · 1224 阅读 · 0 评论 -
leetcode3 longest Substring Without Repeating Characters
刚开始还尼玛各种优化,怕n*n的时间复杂度还通不过,再想能不能简化一下,最后发现暴力破解直接AC,我太高估它了......题意就是给你一个字符串,求出这个字符串的最长子串,但是这个子串是有规则的,就是不能有重复的字符,我是从第一个字符开始遍历到最后一个字符,因为最长的子串一定是以其中一个字符为开头,我逐个统计一遍最长子串就OK了,其实刚才我有想了一下,这个其实也不是n*n的时间复杂度,因为字符原创 2015-09-01 01:43:41 · 1375 阅读 · 0 评论 -
leetcode4 Median of Two Sorted Arrays
给出两个有序的数组,求其中位数,元素个数位偶数个,则求其上中位数和下中位数的平均数.最简单粗暴的做法就是直接从两个数组的开头对比,建立两个指针遍历数组,时间为O(n+m).(数组1长度为n数组2长度为m)如果想要log的时间复杂度就得使用二分了,如果是计算其中位数,序列中必然有(m+n)/2个数小于中位数mid,我们就根据这个公式就可以进行二分,我们先取数组1的中位数mid1,数组1中有n原创 2015-09-08 17:06:13 · 1063 阅读 · 0 评论 -
leetcode9 Palindrome Number
题意:给予一个整数,判断其是否为回文数,负数直接返回false.二次AC,开始时以为负数也算是回文数,但是事实不是这样的.转换成了字符串,依次对比就ok了,代码里运用了itoa的源码.#include#include#include#include#include#include#includeusing namespace std;class Solution {p原创 2015-09-09 20:01:04 · 1082 阅读 · 0 评论 -
leetcode6 ZigZag Conversion
这个leetcode的题写的就是太简单了,测试用例就一个,总是理解错,这个让我很闹心啊.大概题意就是,将字符串排列成连续的折线,就像是很多个N连在一起那种,之后再按行相加然后返回就OK了.仔细观察图形可以发现,第一行和最后一行是可直接循环相加的,不需要加中间的那些字符,字符串的循环周期为crcle = (numRows-1)*2;比如说举一个numRows为6的例子,crc原创 2015-09-08 20:47:48 · 1027 阅读 · 0 评论 -
leetcode8 String to Integer (atoi)
题意:给出一个字符串,将其转换为整数取整规则1.如果整数超出int的范围则返回最大值或者最小值(-2147483648~2147483647)2.字符串的开始可以有空格,如" -1234"3.如果遇到不符合规则的字符串则返回当前已经计算的值,如果一开始就不符合则返回0,如" -+=1234"返回0,"-2324def2"返回-232.整体大概就这些规则,只要注意原创 2015-09-09 19:05:36 · 1156 阅读 · 0 评论 -
leetcode7 Reverse Integer
这道题其实就一个难点就是溢出问题,因为有的数翻转之后会超出int型的上下限,4byte的int型为-2147483648~2147483647.其实最简单的方法就是建立两个long型的变量,然后通过long型提前判断之后在返回.简单粗暴的方法就是全部转换成正数去判断,之后在返回的时候在加负号.下面的代码写的比较乱,就是取正负的地方有些冗余.#include "stdio原创 2015-09-08 23:04:32 · 937 阅读 · 0 评论