时间复杂度

HBase表的设计(一)

岁酱吖の 提交于 2020-01-11 16:48:06
HBase表模式的设计  对于HBase表,在设计表结构之前,我们需要先考虑的几个问题: 这个表应该有多少个列族? 列族使用的是什么数据? 每个列族应该有多少列? 列名应该是什么?尽管列名不必在建表的时候定义,但是后期读写数据时是需要知道的。 单元存放什么数据? 每个单元存储多少个时间版本? 行健结构是什么?应该包含什么信息? 模式影响到表结构和如何读写表,所以说把这些放到宽泛的模式设计中变得尤为重要。 一、HBase的存储方式    HBase底层物理存储是基于HDFS,在HDFS上是以HFile的形式进行存储的: 表中的列族在HDFS上是以HFile的形式存在,一个HFile对应一个列族,但是一个列族可能会对应多个HFile。    一个特定的列族的所有数据在HDFS上会有一个物理存储,这个物理存储区可能会有多个HFile组成,理论上可以通过合并来得到一个HFile,一个列族的所有列在硬盘上是存放在一起的,使用这个特性,可以把不同模式的列放在不同的列族,以便隔离他们。这也是HBase面相列族存储的原因。 二、宽表与高表 宽表:   HBase中所谓的宽表,指的是表中行少而列多,也就是说一行当中包含有很多的列,但是表整体行很少,比如一张表中行健一共有100个,但是每个行健所包含的列有1000个,这种就是所谓的宽表。 高表       HBase中所谓的高表,恰好与宽表相反,行多

两个数组的交集

流过昼夜 提交于 2020-01-11 06:59:42
题目描述 public class Intersection { public static void main ( String [ ] args ) { } } /** * 两个数组的交集 * 题目描述 * 给定两个数组,编辑一个函数来计算他们的交集 * 示列1: * 输入:nums1 = [1,2,2,1], nums2 = [2,2] * 输出:[2] * 示列2: * 输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4] * 输出:[9,4] * 说明: * 输出结果中的每个元素一定是唯一的。 * 我们可以不考虑输出的结果。 */ 方法一的解题思路 * 解法一 * 思路: * 幼稚的方法是根据第一个数组nums1迭代并检查每个值是否存在在nums2内。如果存在就添加到输出。 * 这样的方法会导致 O ( n * m ) 的时间复杂度,其中n和m是数组的长度。 * * 为了在线性时间内解决这个问题,我们使用集合set,在 O ( 1 ) 时间复杂度实现操作 * * 其思想是将两个数组转换为集合set,然后迭代较小的集合检查是否存在较大集合中。这种方法的时间复杂度为 O ( n + m ) . * * / class Solution { public int [ ] intersection ( int [ ] nums1 , int [ ]

优先级队列与堆排序

偶尔善良 提交于 2020-01-11 04:12:32
转自:http://www.cnblogs.com/yangecnu/p/Introduce-Priority-Queue-And-Heap-Sort.html 在很多应用中,我们通常需要按照优先级情况对待处理对象进行处理,比如首先处理优先级最高的对象,然后处理次高的对象。最简单的一个例子就是,在手机上玩游戏的时候,如果有来电,那么系统应该优先处理打进来的电话。 在这种情况下,我们的数据结构应该提供两个最基本的操作,一个是返回最高优先级对象,一个是添加新的对象。这种数据结构就是优先级队列(Priority Queue) 。 本文首先介绍优先级队列的定义,有序和无序数组以及堆数据结构实现优先级队列,最后介绍了基于优先级队列的堆排序(Heap Sort) 一 定义 优先级队列和通常的栈和队列一样,只不过里面的每一个元素都有一个”优先级”,在处理的时候,首先处理优先级最高的。如果两个元素具有相同的优先级,则按照他们插入到队列中的先后顺序处理。 优先级队列可以通过链表,数组,堆或者其他数据结构实现。 二 实现 数组 最简单的优先级队列可以通过有序或者无序数组来实现,当要获取最大值的时候,对数组进行查找返回即可。代码实现起来也比较简单,这里就不列出来了。 如上图: · 如果使用无序数组,那么每一次插入的时候,直接在数组末尾插入即可,时间复杂度为O(1),但是如果要获取最大值

素数筛法—时间复杂度O(n)

让人想犯罪 __ 提交于 2020-01-11 01:01:13
请你想出一个算法求出n以内(含n)的所有素数,要求算法的时间复杂度越小越好。 这里介绍一种算法——快速线性素数筛法(欧拉筛法),时间复杂度O(n)。 诀窍在于:筛除合数时,保证每个合数只会被它的最小质因数筛去。因此每个数只会被标记一次,所以算法时间复杂度为O(n)。 具体请看下面的代码,主要函数是Prime(n)。 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 vector<int> Prime(int n) { // 求解n以内(含n)的素数 6 bool flag[n + 1]; // 标记数组,flag[i]==0表示i为素数,flag[i]==1表示i为合数 7 memset(flag, 0, sizeof(flag)); 8 vector<int> prime; 9 int cnt = 0; // 素数个数 10 for (int i = 2; i <= n; ++i) { 11 if (!flag[i]) { 12 prime.push_back(i); // 将i加入素数表 13 cnt++; 14 } 15 for (int j = 0; j < cnt; ++j) { // 保证每个合数只会被它的最小质因数筛去 16 if (i * prime[j] > n) break; 17 flag[i *

排序算法的指标性能比较

孤者浪人 提交于 2020-01-10 20:22:16
表一 排序方法 平均时间复杂度 最好时间复杂度 最坏时间复杂度 辅助空间 稳定性 冒泡排序 O(n 2 ) O(n) O(n 2 ) O(1) 稳定 简单选择排序 O(n 2 ) O(n 2 ) O(n 2 ) O(1) 稳定 直接插入排序 O(n 2 ) O(n) O(n 2 ) O(1) 稳定 希尔排序   O(nlogn)~O(n 2 ) O(n 1.3 ) O(n 2 ) O(1) 不稳定 堆排序 O(nlogn) O(nlogn) O(nlogn) O(1) 不稳定 归并排序 O(nlogn) O(nlogn) O(nlogn) O(n) 稳定 快速排序 O(nlogn) O(n) O(n 2 ) O(logn)~O(n) 不稳定 一,七种排序算法的性能指标说明: (1)冒泡排序:最坏的情况,即为序列处于逆序的情况,此时需要比较的次数为n(n-1)/2;最好的情况就是序列本身有序,那么需要比较的次数为n-1次,平均o(n 2 ) (2)简单选择排序:无论最好最差情况,其比较次数均为n(n-1)/2,对于交换次数而言,最好的情况,交换0次,最差的情况,交换次数为n-1次,那么综合比较和交换的次数,平均时间复杂度为o(n 2 ) (3)直接插入排序:最好的情况,即排序表本身是有序的,比较了n-1次,时间复杂度为o(n);最坏的情况,即待排序为逆序,此时需要比较(n+2)*(n

Python里面几种排序算法的比较,sorted的底层实现,虽然我们知道sorted的实现方式,但是

半世苍凉 提交于 2020-01-10 18:45:58
算法与数据结构基础 原文链接: http://note.youdao.com/noteshare?id=7b9757930ce3cc9e0a5e61e4d0aa9ea2&sub=2726FFA02ADE4E74A302D8DA7646FB46 查找算法: 二分查找法: 简介 :二分查找法又被称为折半查找法,用于预排序的查找问题 过程 : 如果在列表a中查找元素t,先将列表a中间位置的项与查找关键字t比较,如果两者相等,则成功。 否则,将表分为前后两个子表 如果中间位置大于t,则进一步查找前一子表,否则,查找后一子表 重复上述过程 优劣 : 时间复杂度为O(log~2~N),比较快 缺点就是必须是有序列表 排序算法: 冒泡排序 简介 :两两比较大小,如果不满足升序关系,则交换 过程 :略 优劣: : 时间复杂度为O(N^2^),速度较慢 稳定 选择排序 简介 :找出最小值,然后放入一个新的列表中 过程 :略 优劣: : 时间复杂度为O(N^2^),速度较慢 稳定 插入排序法 简介 :依次检查需要排序的列表,每次取出一个元素放入另一个排好序的列表中的适当位置。 过程 :略 优劣: : 时间复杂度为O(N^2^) 速度不稳定,最佳情况为线性增长,最差情况为N^2^,所以速度实际上比前两种快 归并排序 简介 :分而制之的思想 过程 : 将包含N个元素的列表分为两个含N/2元素的子列表.

Python 堆与堆排序

我是研究僧i 提交于 2020-01-10 07:02:09
堆排序 与 快速排序 , 归并排序 一样都是时间复杂度为O(N*logN)的几种常见排序方法。学习堆排序前,先讲解下什么是数据结构中的二叉堆。 二叉堆的定义 二叉堆是完全二叉树或者是近似完全二叉树。 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。 2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。 当父结点的键值总是大于或等于任何一个子节点的键值时为 最大堆 。当父结点的键值总是小于或等于任何一个子节点的键值时为 最小堆 。下图展示一个最小堆: 由于其它几种堆(二项式堆,斐波纳契堆等)用的较少,一般将二叉堆就简称为堆。 堆的存储 一般都用数组来表示堆,i结点的父结点下标就为(i – 1) / 2。它的左右子结点下标分别为2 * i + 1和2 * i + 2。如第0个结点左右子结点下标分别为1和2。 堆的操作——插入删除 下面先给出《 数据结构 C++语言描述》中最小堆的建立插入删除的图解,再给出本人的实现代码,最好是先看明白图后再去看代码。 堆的插入 每次插入都是将新数据放在数组最后。可以发现从这个新数据的父结点到根结点必然为一个有序的数列,现在的任务是将这个新数据插入到这个有序数据中——这就类似于 直接插入排序 中将一个数据并入到有序区间中,对照 《白话经典算法系列之二 直接插入排序的三种实现》

堆和堆排序

大憨熊 提交于 2020-01-10 07:01:26
堆排序 与 快速排序 , 归并排序 一样都是时间复杂度为O(N*logN)的几种常见排序方法。学习堆排序前,先讲解下什么是数据结构中的二叉堆。 二叉堆的定义 二叉堆是完全二叉树或者是近似完全二叉树。 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。 2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。 当父结点的键值总是大于或等于任何一个子节点的键值时为 最大堆 。当父结点的键值总是小于或等于任何一个子节点的键值时为 最小堆 。下图展示一个最小堆: 由于其它几种堆(二项式堆,斐波纳契堆等)用的较少,一般将二叉堆就简称为堆。 堆的存储 一般都用数组来表示堆,i结点的父结点下标就为(i – 1) / 2。它的左右子结点下标分别为2 * i + 1和2 * i + 2。如第0个结点左右子结点下标分别为1和2。 堆的操作——插入删除 下面先给出《数据结构C++语言描述》中最小堆的建立插入删除的图解,再给出本人的实现代码,最好是先看明白图后再去看代码。 堆的插入 每次插入都是将新数据放在数组最后。可以发现从这个新数据的父结点到根结点必然为一个有序的数列,现在的任务是将这个新数据插入到这个有序数据中——这就类似于 直接插入排序 中将一个数据并入到有序区间中,对照 《白话经典算法系列之二 直接插入排序的三种实现》

栈、时间复杂度

ぐ巨炮叔叔 提交于 2020-01-08 16:38:07
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 栈的知识点学习: 使用栈首先需要创建栈对象:Stack stack = new Stack(); 栈的基本方法: 置空栈:InitStack(s); 判栈空:StackEmpty(s); 判栈满:StackFull(s); 进栈(在栈中插入或者添加):Push(s,x); //进栈的元素都是排在栈顶的 出栈(删除栈中的元素):Pop(s);删除栈顶的数据,并且返回。栈为空删除则会溢出。 取栈顶元素GetTop(s);栈为空会报溢出错误。 时间复杂度: 为什么链表的时间复杂度是O(n)呢?而数组的是O(1)呢? 时间复杂度:就是一个算法执行需要消耗的时间。是这个算法 每条语句的执行时间 之和。 每条语句的执行时间 就是这条语句执行的次数 * 执行的一次的时间之和。 (例如数组和链表:10个数据进行查找和修改,数组只执行一次即可,时间为10秒。而链表需要通过指针依次执行,若该值在第九位则执行了九(n)次,时间为90秒)。 链表和数组的性质区分: 数组是静态数据结构,链表是动态数据结构。 由于链表是空间不连续的,所以链表查找值是需要从头或者尾依次访问判断,语句需要执行n次。不像数组是在一块连续空间,语句只执行1次。 从具体实现上来看 :链表是在不连续的空间内,需要靠指针来依次递进的判断来获取,数组是在一块连续的空间内

归并排序

梦想的初衷 提交于 2020-01-08 14:19:49
对于归并排序,它的时间复杂度是 O(nlogn) ,它的最差时间复杂度是这个,最好的时间复杂度是这个,平均时间复杂度也是这个。 归并排序有一个很重要的思想在里边,那就是分治的思想。 算法的过程其实就两步,一个是分,一个是治。 # # 归并算法的过程图 可以看到的是,所谓的分就是拆分,治就是将两个有序的序列合并成为一个有序的序列。 # # 下边看代码过程 public class MergetSort { public static void main(String[] args) { //int arr[] = { 8, 4, 5, 7, 1, 3, 6, 2 }; // //测试快排的执行速度 // 创建要给80000个的随机的数组 int[] arr = new int[8000000]; for (int i = 0; i < 8000000; i++) { arr[i] = (int) (Math.random() * 8000000); // 生成一个[0, 8000000) 数 } System.out.println("排序前"); Date data1 = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String