
算法
文章平均质量分 78
zhaoyunfullmetal
这个作者很懒,什么都没留下…
展开
-
编程珠玑——取样总结
取样问题问题描述:程序的输入包含两个整数m和n,其中m小于n。输出是0~n-1范围内的m个随机整数,要求:每个数选择出现的概率相等,且按序输出。问题中最重要的要求是概率相同。假设m=2,n=5,那么每个数都应该以2/5的概率被选中,直观的会想到用这样的代码实现:if((rand()%5)<2)然而这样做是不对的,编程珠玑12章对这个问题进行了详细的介绍。本文于是总结了编程珠玑中等概率取样问题的几种解原创 2015-11-09 10:43:22 · 974 阅读 · 0 评论 -
编程珠玑——快速排序总结
快速排序快速排序是二十世纪最伟大的10大算法之一。如何写好一个快速排序通常不是一件容易的事,同时面试中或者实际应用中也经常要用到快速排序。编程珠玑第11章专门介绍了快速排序,涉及到了基本的算法思想实现和一些优化,这里进行简单的总结以便以后快速的回忆。基本思想快速排序用到了分治,它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此原创 2015-11-07 21:35:50 · 1854 阅读 · 0 评论 -
分治算法求子数组的最大和
求最大子数组和也是一个非常经典的题目。此题目在leetcode,《编程之美》,《算法导论》,《编程珠玑》中都提到了,这是一个能显著体现出算法设计重要性的题目。通过不断地优化算法设计,该题目能够不断以更好更快的时间被解决。先看一下题目描述: 题目描述: 输入一个整形数组,数组里有正数也有负数。 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。 求所有子数组的和的最大值。要求时原创 2015-11-03 21:27:00 · 1314 阅读 · 0 评论 -
二分查找
二分查找二分查找是一种用于有序数列的折半查找算法。二分查找优点是比较次数少,查找速度快,平均性能好;时间复杂度为O(lgN)。因此二分查找也成为了面试中的常问问题。但是要写出一个完全正确的二分查找并不容易,下面我们先来看个错误的二分查找。(以下大部分是对编程珠玑章节的总结)错误的二分查找int binarySearch(vector<int> x,int t){ int mid,l=0;原创 2015-10-28 16:08:31 · 3064 阅读 · 0 评论 -
牛顿迭代法实现平方根函数
牛顿迭代法实现平方根函数平方根函数Sqrt() 用来求一个数的平方根,如何实现这个函数?有多种方法,这里记录一种比较常用的牛顿迭代法。牛顿迭代法 牛顿迭代法(Newton·s method)又称为牛顿-拉夫逊(拉弗森)方法(Newton-Raphson method),它是牛顿在17世纪提出的一种在实数域和复数域上近似求解方程的方法。多数方程不存在求根公式,因此求精确根非常困难,甚至不可能,从而原创 2015-10-20 21:15:06 · 3656 阅读 · 0 评论 -
删除二叉树
删除一个二叉树很简单,但是通常我们是用递归的方式,若用迭代的方式则需要额外的空间来保存信息。如何在O(N)的时间内使用O(1)的空间来完成二叉树空间的释放呢?这是我在面试中遇到的一个问题.Morris中序遍历利用Morris中序遍历可以在O(1)的空间O(N)的时间复杂度内遍历完成二叉树,因此可以在遍历的过程中完成树的空间的释放。我之前转载过Morris遍历二叉树的一篇文章,详细看这里: Morr原创 2015-09-01 11:53:55 · 2686 阅读 · 0 评论 -
Morris方法遍历二叉树
本文主要解决一个问题,如何实现二叉树的前中后序遍历,有两个要求:O(1)空间复杂度,即只能使用常数空间;二叉树的形状不能被破坏(中间过程允许改变其形状)。通常,实现二叉树的前序(preorder)、中序(inorder)、后序(postorder)遍历有两个常用的方法:一是递归(recursive),二是使用栈实现的迭代版本(stack+iterative)。这两种方法都是O(n)的空间复杂度转载 2015-08-29 16:27:40 · 3721 阅读 · 1 评论 -
求二叉搜索树任一节点的前驱后继节点
二叉搜索树节点的前驱后继节点之前写过文章介绍了二叉搜索树以及其上的基本操作,但不包括求节点的前驱结点和后继节点。这是一个很老的问题了,首先看下某节点前驱和后继节点的定义。一个节点的 前驱结点:节点val值小于该节点val值并且值最大的节点 后继节点:节点val值大于该节点val值并且值最小的节点算法导论中给出了详细的求前驱结点和后继节点的算法,但是其中的节点数据结构包含了指向父亲节点的指针,但是原创 2015-08-27 20:55:58 · 13221 阅读 · 3 评论 -
LCA-最小公共父节点
有一个普通二叉树,AB分别为两个子节点,求AB最近(深度最浅)的公共父节点。 此题仍然是一个老题,有着多种解决方法,本文针对其中三种方法来进行分析总结。这三种方法分别是:递归法,tarjan离线算法,RMQ在线算法。递归法递归法比较直观简单,思路如下:首先判定当前节点root是否是A节点或者B节点,若是的话直接返回该节点若不是,分别对root节点的左右子树进行递归查找最小公共原创 2015-07-19 10:37:22 · 5115 阅读 · 0 评论 -
RMQ-区间最值问题
区间最值询问是求给定区间最值的问题。若总区间为[1,N],通常是有多次查询,每次查询是不同的总区间的子区间。简单的方法是对每个子区间遍历从而找到最值,时间复杂度是O(N),但是如果有多次的查询,效率就会很低。而解决这个问题的一个很好的在线算法便是ST(Sparse_Table)算法算法思想预处理ST算法在O(nlogn)的预处理以后可以实现O(1)的查询效率。也就是说我们把大量的区间的最值预先求出来原创 2015-07-15 16:14:44 · 1342 阅读 · 0 评论 -
Leetcode : Regular Expression Matching
对于leetcode上这个题目,我用了不少时间来消化。题目大意如下:实现两个字符串s,t的匹配,其中t字符串中的 ‘.’ 能匹配任何一个字符. ‘*’ 能充当0个或者多个前面一个字符. 匹配结果要覆盖整个字符串几个例子: isMatch(“aa”,”a”) → false isMatch(“aa”,”aa”) → true isMatch(“aaa”,”aa”) → f原创 2015-07-08 15:45:31 · 609 阅读 · 0 评论 -
最长上升子序列
这是一道老题,有两种思路,时间复杂度分别是O(n^2)和O(nlgn). O(n^2)的方法是典型的DP思路,较为常见,现在整理下O(nlgn)的算法思路。算法思路最长上升子序列的查找用到了多个数组。a数组作为存储原始数据的数组,该算法的实现过程就是将a数组中每个元素插入c数组中的过程,而c数组中最后剩余的a数组中的元素个数即是最长上升序列的长度。原因如下: 最长上升序列中的元素大小一定是递增,利原创 2015-07-04 09:31:38 · 477 阅读 · 0 评论 -
最长回文子串
最长回文子串题意:给定一个字符串s,找出该字符串中最长的回文子串。字符串如“abcba”,”abbbba”这样呈中心对称的子串称为回文串。该题目是一个老题了,有多种不同的解法,我整理一下方便以后查询。暴力动态规划法这个方法是我们看到这个题目后最容易想到的方法,暴力搜索所有的子串,判断每个子串是否是回文串;我们用一个二维空间记录已计算过的子串是否为回文串,这样之后针对每个新子串进原创 2015-06-30 19:36:49 · 723 阅读 · 0 评论 -
数组中第K大元素
数组中第K大元素在面试的时候遇到过这个问题,后来在leetcode上也遇到了这个问题,于是记录下来以便以后快速回忆。题目有多种思路,全排序是比较直观的想法,然而最低的时间复杂度为O(nlgn),并且不符合该题目的初衷。题目更多想问的是如何在不进行全排序的条件下找到数组中第K大的元素,个人认为比较被面试官中意的解答有两个(理应也有其他的..),如下:构建最大堆简单分析时间复杂度: 构建堆的时间O(n)原创 2015-06-27 22:08:50 · 3333 阅读 · 0 评论 -
拓扑排序
拓扑排序拓扑排序的定义 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列—— [ 百度百科 ]拓扑排序表示了顶点按照边的方向出现的先后顺序。原创 2015-06-20 16:21:18 · 1066 阅读 · 0 评论 -
二叉树的创建
二叉树的创建以前文章里面提到过二叉树的遍历分三种方式,前序遍历,中序遍历和后序遍历,那么二叉树的构建过程也可以分这三种顺序,最常用的应该是先序创建二叉树,比较符合我们的直观想法。 我在实际中遇到的二叉树的创建问题较少,更多的是给定一个二叉树然后对二叉树进行操作。最近遇到了几个题目,跟二叉树的创建有关,也是考验算法的题目,现在记录一下。根据中序和后序遍历顺序构建二叉树这个题目一开始原创 2015-04-30 22:02:42 · 779 阅读 · 0 评论 -
KMP算法小总结
KMP算法小总结字符串匹配是编程常遇到的一个问题,最朴素简单粗暴的匹配方法需要O(n2)O(n^2)的时间复杂度,这显然满足不了算法大神的要求。KMP算法是一种改进的快速的字符串匹配算法,是由D.E.Knuth与V.R.Pratt和J.H.Morris同时发现,算法的时间复杂度只需要O(n)。算法思想其实很简单,但是有时候会被人们解释的很复杂,因此我想根据我的经验来简单的总结一下KMP算法以便我自己原创 2015-04-30 21:49:57 · 662 阅读 · 0 评论 -
窗口有关算法题目
窗口算法窗口算法是我自己起的不严谨的名字,因为最近做了几个leetcode中几个算法题目,发现其算法的都需要通过维护一个窗口来实现,说到窗口,我们肯定会想到TCP/IP中的滑动窗口协议,其实这类算法题目和这个有点神似的。 滑动窗口协议是用来改善吞吐量的一种技术,TCP中采用滑动窗口来进行传输控制,滑动窗口的大小意味着接收方还有多大的缓冲区可以用于接收数据。——百度百科现在我汇总一下,分析一下这原创 2015-04-21 22:31:17 · 651 阅读 · 0 评论 -
二叉树的遍历
二叉树的遍历二叉树是一种常用并且重要的数据结构,其是每个节点最多有两个子树的树结构。通常子树被称作“左子树”和“右子树”。二叉树中一个比较常用的操作是遍历二叉树。 所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问 题。 遍历是二叉树上最重要的运算之一,是二叉树上进行其它运算之基础。 ———-[百度百科原创 2015-04-15 19:45:19 · 677 阅读 · 1 评论 -
常用位运算算法题目
常用位运算算法题目位运算操作简单,高效,可以提升算法编程的效率,下面让我们讨论几个常用的位运算算法。求二进制中1的个数这个题目有在编程之美里面出现,最基本的思路就是一个数除以2,原来的二进制数目会减少一个,若是除的过程中有余数,那么就表示当前位置有一个1.除以2可以用>>操作,判断是否有余数1可以用&操作。int hammingWeight(uint32_t n) { int num=0原创 2015-04-14 20:26:36 · 1323 阅读 · 0 评论