时间复杂度

海量数据中的TopK问题

青春壹個敷衍的年華 提交于 2019-12-08 18:34:14
1. 抛出问题 在大规模数据处理中,经常会遇到的一类问题:在海量数据中找出出现频率最好的前k个数,或者从海量数据中找出最大的前k个数,这类问题通常被称为top K问题。例如,在搜索引擎中,统计搜索最热门的10个查询词;在歌曲库中统计下载最高的前10首歌等。 针对top K类问题,通常比较好的方案是分治+Trie树/hash+小顶堆(就是上面提到的最小堆),即先将数据集按照Hash方法分解成多个小数据集,然后使用Trie树活着Hash统计每个小数据集中的query词频,之后用小顶堆求出每个数据集中出现频率最高的前K个数,最后在所有top K中求出最终的top K。 eg:有1亿个浮点数,如何找出其中最大的10000个? 2. 如何解决 1)全局排序法 这是最容易想到的方法,将数据全部排序,然后在排序后的集合中进行查找,最快的排序算法的时间复杂度一般为O(nlogn),如快速排序。 但是在32位的机器上,每个float类型占4个字节,1亿个浮点数就要占用400MB的存储空间,对于一些可用内存小于400M的计算机而言,很显然是不能一次将全部数据读入内存进行排序的。其实即使内存能够满足要求(我机器内存都是8GB),该方法也并不高效,因为题目的目的是寻找出最大的10000个数即可,而排序却是将所有的元素都排序了,做了很多的无用功。 2)局部淘汰法 该方法与全局排序法类似

【大数据】海量数据处理方法

不问归期 提交于 2019-12-08 17:58:33
  1、海量日志数据,提取出某日访问百度次数最多的那个IP。     首先是这一天,并且是访问百度的日志中的IP取出来,逐个写入到一个大文件中。注意到IP是32位的,最多有个2^32个IP。同样可以采用映射的方法,比如模1000,把整个大文件映射为1000个小文件,再找出每个小文中出现频率最大的IP(可以采用hash_map进行频率统计,然后再找出频率最大的几个)及相应的频率。然后再在这1000个最大的IP中,找出那个频率最大的IP,即为所求。   或者如下阐述(雪域之鹰):   算法思想:分而治之+Hash   1.IP地址最多有2^32=4G种取值情况,所以不能完全加载到内存中处理;   2.可以考虑采用“分而治之”的思想,按照IP地址的Hash(IP)%1024值,把海量IP日志分别存储到1024个小文件中。这样,每个小文件最多包含4MB个IP地址;   3.对于每一个小文件,可以构建一个IP为key,出现次数为value的Hash map,同时记录当前出现次数最多的那个IP地址;   4.可以得到1024个小文件中的出现次数最多的IP,再依据常规的排序算法得到总体上出现次数最多的IP;     2、搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节。   假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万

数据结构中涉及的排序算法

末鹿安然 提交于 2019-12-07 22:06:21
下面按照课本的分类,做了大致的内排序的归类的图片: 下面我们逐个来实现排序的算法: 一、插入排序算法: 包括:直接插入、折半插入、和希尔排序 其中,插入排序的思想都是一样的,都是以首个待排序的数字作为假设已经有序的序列,然后从已经有序的序列的最后一个位置,从后往前找满这趟比较中元素适合放置的位置。 1. 直接插入插入排序: /* 直接插入插入排序,假定首个元素有序, 待插入元素和前面的元素依次大小比较, 如果满足该元素小于前面一次由后到前的元素,就依次移动元素 循环判断 时间复杂度O(n^2) 稳定排序 基本有序时时间复杂度为O(n) */ void insertSort1(int a[], int n){ //直接插入排序 int temp,j; for(int i=1;i<n;i++){ temp = a[i]; j = i-1; while(j>=0 and temp<a[j]){ //逐个元素比较,逐个移动元素 a[j+1] = a[j]; j--; } a[j+1] = temp; } } void insertSort2(int a[], int n){ int i, j, temp; for(i=1;i<n;i++){ temp = a[i]; for(j=i-1;temp<a[j] and j>=0;j--){ a[j+1] = a[j]; } a[j+1] =

数据结构之排序算法

痞子三分冷 提交于 2019-12-07 22:01:12
作者:离散梦 欢迎大家给出宝贵的建议! 数据结构之排序算法 稳定排序 :冒泡、插入、归并、基数 不稳定排序 :选择、快速、希尔、堆 口诀就是: 快 (快速) 些 (希尔) 选 (选择) 一 堆 (堆) 好朋友来玩吧! 1.冒泡排序 冒泡排序(Bubble Sort)一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。【时间复杂度为O(n^2),最好的情况就是有序的时候为O(n)】 算法思想过程: 冒泡排序算法——python实现程序 2.选择排序 选择排序(Selection Sort )就是通过n-i次关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1<=i<=n)个记录交换之。【时间复杂度为O(n^2)】 算法思想过程: 选择排序算法——python实现程序 3.插入排序 插入排序(Insertion Sort)的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表。【时间复杂度为O(n^2),最好的情况是排好序的时候为O(n)】 算法思想过程: 注:下面排序之后答案是1,2,3,4,5,6,7,8.我下面这幅图有些许错误,就不重新作图了。 插入排序算法——python实现程序 4.归并排序 归并排序(Merging Sort)就是利用归并的思想实现的排序方法

【PTA】【数据结构与算法】堆

做~自己de王妃 提交于 2019-12-07 16:15:18
判断题 1.任何最小堆的前序遍历结果是有序的(从小到大)。 (2分) T F 2.任何最小堆中从根结点到任一叶结点路径上的所有结点是有序的(从小到大)。 (2分) T F 3.在有N个元素的最大堆中,随机访问任意键值的操作可以在O(logN)时间完成。 (2分) T F 4.一棵有124个结点的完全二叉树,其叶结点个数是确定的。 (2分) T F 5.完全二叉树中,若一个结点没有左孩子,则它必是树叶。 (1分) T F 6.完全二叉树的存储结构通常采用顺序存储结构。 (1分) T F 选择题 1.堆的形状是一棵: (2分) 选项 A 二叉搜索树 B 满二叉树 C 非二叉树 D 完全二叉树 2.创建一个初始堆,含有N个记录,其时间复杂度是: (2分) 选项 A O(logN) B O(N) C O(NlogN) D O(N 2 ) 3.哪种树,树中任何结点到根结点路径上的各结点值是有序的? (2分) 选项 A 二叉搜索树 B 完全二叉树 C 堆 D 以上都不是 4.将6、4、3、5、8、9顺序插入初始为空的最大堆(大根堆)中,那么插入完成后堆顶的元素为: (2分) 选项 A 3 B 5 C 6 D 9 5.下列的序列中,哪一组是堆? (2分) 选项 A 37,99,45,33,66,10,22,13 B 99,45,66,13,37,10,22,33 C 99,66,45,33,37

字典树 && 例题 Xor Sum HDU - 4825 (板子)

岁酱吖の 提交于 2019-12-07 12:50:26
一、字典树描述: Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计 和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大 限度地减少无谓的字符串比较,查询效率比哈希表高。 Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。 它有3个基本性质: 1、根节点不包含字符,除根节点外每一个节点都只包含一个字符。 2、从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。 3、每个节点的所有子节点包含的字符都不相同。 二、字典树时间复杂度: 问题: 有一个存放英文单词的文本文件,现在需要知道某些给定的单词是否在该文件中存在,若存在,它又出现了多少次? (暴力方法就不说了) 解法一: 如果将所有的单词都存放在一个map中,每次查找的时间复杂度则降为O(log(n))。 解法二: 假设所有字符串长度之和为n,构建字典树的时间复杂度为O(n)。假设要查找的字符串长度为k,查找的时间复杂度为: O(k)(也相当于O(1))。 三、字典树构建: 举个在网上流传颇广的例子,如下: 题目:给你100000个长度不超过10的单词。对于每一个单词,我们要判断他出没出现过,如果出现了,求第一次出现在第几个位置。 分析:这题当然可以用hash来解决

ARTS打卡第四周

余生长醉 提交于 2019-12-07 11:43:34
Algorithm 只出现一次的数字 给定一个 非空 整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 说明: 你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗? 示例 1: 输入: [2,2,1] 输出: 1 示例 2: 输入: [4,1,2,1,2] 输出: 4 刚接触这类型的题目,连时间复杂度,和空间复杂度是什么都不太清楚,查了下资料才知道。 时间复杂度,为线性就是,可以有单次循环,不能有嵌套循环,因为嵌套循环涉及到了平方,就是不是线性的了。 Tip java 中 的异或运算 运算规则:两个书转化成二进制,从高位开始比较,相同为0,不同1 比如: 比如:8^11. 8转为二进制是1000,11转为二进制是1011.从高位开始比较得到的是:0011.然后二进制转为十进制,就是Integer.parseInt("0011",2)=3; 参考文章: http://www.cnblogs.com/yesiamhere/p/6675067.html 还有篇,讲解什么是时间复杂度的文章:https://blog.csdn.net/qq_41523096/article/details/82142747 这周其他的没有做到 转载于:https://www.cnblogs.com/prader6/p/10787907.html 来源:

一文教你学会递归解题

↘锁芯ラ 提交于 2019-12-06 23:48:32
前言 递归是算法中一种非常重要的思想,应用也很广,小到阶乘,再在工作中用到的比如统计文件夹大小,大到 Google 的 PageRank 算法都能看到,也是面试官很喜欢的考点 最近看了不少递归的文章,收获不小,不过我发现大部分网上的讲递归的文章都不太全面,主要的问题在于解题后大部分都没有给出相应的时间/空间复杂度,而时间/空间复杂度是算法的重要考量!递归算法的时间复杂度普遍比较难(需要用到归纳法等),换句话说,如果能解决递归的算法复杂度,其他算法题题的时间复杂度也基本不在话下。另外,递归算法的时间复杂度不少是不能接受的,如果发现算出的时间复杂度过大,则需要转换思路,看下是否有更好的解法 ,这才是根本目的,不要为了递归而递归! 本文试图从以下几个方面来讲解递归 什么是递归? 递归算法通用解决思路 实战演练(从初级到高阶) 力争让大家对递归的认知能上一个新台阶,特别会对递归的精华:时间复杂度作详细剖析,会给大家总结一套很通用的求解递归时间复杂度的套路,相信你看完肯定会有收获 什么是递归 简单地说,就是如果在函数中存在着调用函数本身的情况,这种现象就叫递归。 以阶乘函数为例,如下, 在 factorial 函数中存在着 factorial(n - 1) 的调用,所以此函数是递归函数 public int factorial(int n) { if (n < =1) { return 1;

排序算法:桶排序、计数排序、基数排序

Deadly 提交于 2019-12-06 22:29:39
相关博客: 排序算法:冒泡排序、插入排序、选择排序、希尔排序 排序算法:归并排序、快速排序 排序算法:桶排序、计数排序、基数排序 排序算法:堆排序 十大排序算法小结 这篇博客将主要介绍三种时间复杂度是O(n)的排序算法:桶排序、计数排序、计数排序。因为这些排序算法的时间复杂度都是线性的,所以也把这类排序算法称为 线性排序。 之所以能够做到线性的时间复杂度,主要原因是这几个算法是非基于比较的排序算法,不涉及元素之间的比较操作。 这几种排序算法的时间复杂度虽然低,但是对要排序的数据要求比较苛刻,所以我们关键是要知道这些排序算法的 适用场景 。 一、桶排序: 1、算法原理: 桶排序的核心思想就是将要排序的数据分到几个有序的桶里,每个桶里的数据再单独进行排序。桶排序完之后,再把每个桶里的数据按照顺序依次取出,组成的序列就是有序的了。 2、图片演示: 3、桶排序的时间复杂度为O(n): 如果要排序的数据有 n 个,我们把它们均匀地划分到 m 个桶内,每个桶里就有 k=n/m 个元素。每个桶内部使用归并排序,时间复杂度为 O(k * logk)。m 个桶排序的时间复杂度就是 O(m * k * logk),因为 k=n/m,所以整个桶排序的时间复杂度就是 O(n*log(n/m))。当桶的个数m 接近数据个数 n 时,log(n/m) 就是一个非常小的常量,这个时候桶排序的时间复杂度接近 O