数据结构与算法
muweiyou
这个作者很懒,什么都没留下…
展开
-
欧拉回路
欧拉回路:一个回路,该回路恰好经过每条边一次。终点必须终止在起点上的欧拉回路只有当图是连通 的并且每个顶点的度(即边的条数)是偶数时才有可能存在。这是因为,在欧拉回路中,一个顶点 有边进入,则必然有边离开。如果任一顶点v的度为奇数,那么最终会达到这样一种地步,即只有一条进入v的边尚未访问到,若沿该边进入v点,那么只能停在顶点v,不可能再出来。如果恰好有两个顶点的度是奇数,那么当从一个奇原创 2012-04-25 09:23:40 · 4246 阅读 · 0 评论 -
找出1到10w中没有出现的两个数字
有1到10w这10w个数,去除2个并打乱次序,如何找出那两个数?方法1:申请10w个bit的空间,每个bit代表一个数字是否出现过。开始时将这10w个bit都初始化为0,表示所有数字都没有出现过。然后依次读入已经打乱循序的数字,并将对应的bit设为1。当处理完所有数字后,根据为0的bit得出没有出现的数字。方法2:首先计算1到10w的和,平方和。然后计算转载 2012-05-09 13:43:54 · 475 阅读 · 0 评论 -
求一个论坛的在线人数,假设有一个论坛,其注册ID有两亿个,每个ID从登陆到退出会向一个日志文件中记下登陆时间和退出时间,要求写一个算法统计一天中论坛的用户在线分布,取样粒度为秒。
求一个论坛的在线人数,假设有一个论坛,其注册ID有两亿个,每个ID从登陆到退出会向一个日志文件中记下登陆时间和退出时间,要求写一个算法统计一天中论坛的用户在线分布,取样粒度为秒。一天总共有 3600*24 = 86400秒。定义一个长度为86400的整数数组int delta[86400],每个整数对应这一秒的人数变化值,可能为正也可能为负。开始时将数组元素都初始化为0。然转载 2012-05-09 14:10:53 · 890 阅读 · 0 评论 -
海量日志数据,提取出某日访问百度次数最多的那个IP。
IP地址最多有2^32=4G种取值可能,所以不能完全加载到内存中。 可以考虑分而治之的策略,按照IP地址的hash(IP)%1024值,将海量日志存储到1024个小文件中。每个小文件最多包含4M个IP地址。 对于每个小文件,可以构建一个IP作为key,出现次数作为value的hash_map,并记录当前出现次数最多的1个IP地址。 有了1024个小文件中的出现次数最多的IP,我们就可以转载 2012-05-09 13:39:09 · 452 阅读 · 0 评论 -
找到两个单向链表的第一个公共节点
如果两个单向链表有公共节点,则两个链表会构成Y型结构,最后一个节点相同。我们可以从头开始遍历两个链表,找到最后一个节点的指针,设为p_a,p_b。同时记录下两个链表的长度len_a,len_b(假设len_a >= len_b)。如果p_a == p_b,则说明两个链表有公共节点,否则没有。如果有公共节点,则第一个公共节点距起始节点的距离满足 len_a - start_a ==转载 2012-05-09 13:58:30 · 505 阅读 · 0 评论 -
如何有效合并两个文件:一个是1亿条的用户基本信息,另一个是用户每天看电影连续剧等的记录,5000万条。其中内存只有1G。
如何有效合并两个文件:一个是1亿条的用户基本信息,另一个是用户每天看电影连续剧等的记录,5000万条。其中内存只有1G。显然内存不能同时存下所有的数据,所以考虑分而治之的思想。假设1K Byte可以保存一个用户的基本信息和看电影记录。1亿=0.1G,所以0.1G*1KB=100GB。内存为1G,分为100个小文件。我们可以将基本信息和看电影记录都按照hash(user_na转载 2012-05-09 14:15:10 · 3291 阅读 · 0 评论 -
最长递增子序列LIS(动态规划+二分查找)
/** =====================================================================================** Filename: LIS.c** Description: 求数组的最长递增子序列的长度(Longest Inceasing SubSequence: LIS)*转载 2012-09-03 13:53:03 · 1131 阅读 · 0 评论 -
用两个队列实现栈
程序员面试精选100题(18)给出了用两个栈实现队列的方法,这种方法不再重述,这里将给出用两个队列实现栈的方法。代码清单如下:#include#include#include#includeusing namespace std;templateclass stack{public: stack(){} ~stack(){} void push(T x); T p原创 2012-09-12 19:54:38 · 636 阅读 · 0 评论 -
创建二叉树(递归)
非递归创建二叉树,需要用到栈,的确太烦了。这里只给出递归创建二叉树的方法。#include "stdafx.h"#includeusing namespace std;typedef struct BiTreeNode{ char data; BiTreeNode* left; BiTreeNode* right;}BiTreeNode,*BiTree;//均为先序创建,即原创 2012-09-13 11:06:42 · 1147 阅读 · 1 评论 -
《编程之美》 3.10 分层遍历二叉树
给定一颗二叉树,要求按分层遍历该二叉树,即从上到下按层次访问该二叉树(每一层将单独输出一行),每一行要求访问的顺序是从左到右。《编程之美》中有递归和非递归的解法。递归解法的思路是,假设要求访问二叉树中第K层的节点,那么可以把它转换成访问以该二叉树根节点的左右节点为根的两颗左右子树的第K-1层的节点。依次递归下面程序是输出第K层的节点int PrintNodeAtLe转载 2012-09-13 19:46:04 · 717 阅读 · 0 评论 -
三、四柱汉诺塔最小步数
三柱汉诺塔最小步数函数为:hntf3(n);四柱汉诺塔最小步数函数为:hntf4(n).int hntf3(int n){ if(n==1) return 1; return 2*hntf3(n-1)+1;}三柱汉诺塔最小步数的规律是:f(n)=2^n-1(n为盘子数)int hntf4(int n){ if(n==1) return 1; int min,u;原创 2012-09-10 22:55:42 · 8362 阅读 · 0 评论 -
从300万字符串中找到最热门的10条(百度面试题)
搜索的输入信息是一个字符串,统计300万输入信息中的最热门的前10条,我们每次输入的一个字符串为不超过255byte,内存使用只有1G。请描述思想,写出算法(c语言),空间和时间复杂度。答案: 此题是可以全部存放入内存中的情况。256B=0.25KB=1KB/4;100万=1M,10亿=1G。300万个字符串最多(假设没有重复,都是最大长度)占用内存3M*1K/4=0.转载 2012-05-09 11:11:02 · 2868 阅读 · 0 评论 -
一个文件中有40亿个整数,每个整数为四个字节,内存为1GB,写出一个算法:求出这个文件里的整数里不包含的一个整数。
4个字节表示的整数,总共只有2^32约等于4G个可能。 为了简单起见,可以假设都是无符号整数。 分配500MB内存,每一bit代表一个整数,刚好可以表示完4个字节的整数,初始值为0。基本思想每读入一个数,就把它对应的bit位置为1,处理完40G个数后,对500M的内存遍历,找出一个bit为0的位,输出对应的整数就是未出现的。算法流程: 1)分配500MB内存buf,初始化为0转载 2012-05-09 14:46:05 · 3885 阅读 · 0 评论 -
Prim最小生成树算法
在一个具有几个顶点的连通图G中,如果存在子图G'包含G中所有顶点和一部分边,且不形成回路,则称G'为图G的生成树,代价最小生成树则称为最小生成树。 许多应用问题都是一个求无向连通图的最小生成树问题。例如:要在n个城市之间铺设光缆,主要目标是要使这 n 个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同;另一个目标是要使铺设光缆的转载 2012-04-24 16:45:38 · 701 阅读 · 0 评论 -
汉诺塔 算法(递归和非递归算法)
算法介绍:其实算法非常简单,当盘子的个数为n时,移动的次数应等于2^n – 1(有兴趣的可以自己证明试试看)。后来一位美国学者发现一种出人意料的简单方法,只要轮流进行两步操作就可以了。首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子A上,根据圆盘的数量确定柱子的排放顺序:若n为偶数,按顺时针方向依次摆放 A B C;若n为奇数,按顺时针方向依次摆放 A C B。(1转载 2011-12-30 10:46:47 · 1133 阅读 · 0 评论 -
堆和栈的区别(转过无数次的文章)
一、预备知识—程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其 操作方式类似于数据结构中的栈。 2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回 收 。注意它与数据结构中的堆是两转载 2012-05-04 09:11:23 · 341 阅读 · 0 评论 -
百度最新面试题集锦
1、实现一个函数,对一个正整数n,算得到1需要的最少操作次数。 操作规则为:如果n为偶数,将其除以2;如果n为奇数,可以加1或减1;一直处理下去。例子:func(7) = 4,可以证明最少需要4次运算n = 7n-1 6n/2 3n-1 2n/2 1要求:实现函数(实现尽可能高效) int func(unsign int n);n为输入,返回最小的运算次数。转载 2012-05-07 17:17:00 · 774 阅读 · 0 评论 -
Top K算法
此算法是不是可解百度搜索中的suggestion问题?问题描述:(百度面试题)搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为0-255字节。假设目前有1000万个记录,除去重复后,不超过300万个。一个查询串的重复度越高,说明查询它的用户越多,也就是越热门,请你统计最热门的10个查询串,要求内存不能超过1G。问题解析:【分析】:要统计最热门查询,首先转载 2012-05-07 17:15:02 · 638 阅读 · 0 评论 -
2012年5月6日 百度实习研发工程师笔试题(通用)
1. 单词a中任意字母交换位置变为单词b,我们就称单词a,b为兄弟单词,如 army 与 mary为兄弟单词。现给一个单词字典,用户输入一个单词,找出字典中所有的兄弟单词,请写出你的解题思路和算法。 答案: (思路一)计算ASCII码,如果值与输入词的ASCII码相等,再判断; (思路二)是对输入的单词进行全排列,对每一种排列在字典里查询,统计查到的兄弟单词个数。(但是这个思转载 2012-05-07 16:23:55 · 880 阅读 · 0 评论 -
从两个文件(各含50亿个url)中找出共同的url
给定a、b两个文件,各存放50亿个url,每个url各占用64字节,内存限制是4G,如何找出a、b文件共同的url?答案: 可以估计每个文件的大小为5G*64=300G,远大于4G。所以不可能将其完全加载到内存中处理。考虑采取分而治之的方法。 遍历文件a,对每个url求取hash(url)%1000,然后根据所得值将url分别存储到1000个小文件(设为a0,a1,...a99转载 2012-05-09 11:15:06 · 842 阅读 · 0 评论 -
在100w个数中找最大的前100个数
应该使用某种数据结构保存迄今最大的100个数。每读到一个新数时,将新数和保存的100个数中的最小一个相比较,如果新数更大些,则替换。这样扫描一遍100w个数也就获得了最大的100个数。对于保存的100个数的数据结构,应该在最小复杂度的条件下满足1)可以获得最小的数;2)将最小数替换为另一个数后可以重新调整,使其可以满足条件1。可见小根堆可以满足这些条件。所以应该采用小根堆+扫描转载 2012-05-09 14:01:51 · 1330 阅读 · 0 评论 -
在一个文件中有 10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。
在一个文件中有 10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。不妨假设10G个整数是64bit的。2G内存可以存放256M个64bit整数。我们可以将64bit的整数空间平均分成256M个取值范围,用2G的内存对每个取值范围内出现整数个数进行统计。这样遍历一边10G整数后,我们便知道中数在那个范围内出现,以及这个范围内总共出现了多少个整数。如果中数所在范围转载 2012-05-09 14:02:30 · 1043 阅读 · 0 评论 -
美丽的Hash
提到Hash,大家都会想到它的“快速存取”,在O(1)时间复杂度里就可以查找到目标元素,或者判断其是否存在,基于Hash我们有HashTable,HashMap等多种数据结构。Hash数据结构里的数据对外是杂乱无序的,我们无法得知其具体存储位置,也不知道各个存储元素位置之间的相互关系,但是我们却可以在常数时间里判断元素位置及存在与否,这不能不说是一个神奇,而这个神奇的创建在数学上却是那么的简单,不转载 2012-05-09 14:36:46 · 576 阅读 · 0 评论 -
判断单链表是否存在环,判断两个链表是否相交问题详解
有一个单链表,其中可能有一个环,也就是某个节点的next指向的是链表中在它之前的节点,这样在链表的尾部形成一环。问题:1、如何判断一个链表是不是这类链表?2、如果链表为存在环,如何找到环的入口点?解答:一、判断链表是否存在环,办法为:设置两个指针(fast, slow),初始值都指向头,slow每次前进一步,fast每次前进二步,如果链表存在环,则fas转载 2012-10-20 22:48:22 · 527 阅读 · 0 评论