算法实现思路

Posted 买糖买板栗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法实现思路相关的知识,希望对你有一定的参考价值。

  • 如何访问链表中间节点:只能遍历一次链表:可以采取建立两个指针,一个指针一次遍历两个节点,另一个节点一次遍历一个节点,当快指针遍历到空节点时,慢指针指向的位置为链表的中间位置,这种解决问题的方法称为快慢指针方法。

  • 怎么查询一个单向链表的倒数第五个节点:定义一个nodeA,然后遍历链表,nodeA与当前遍历的node相差五个节点即可
  • 判断链表是否成环:定义两个node,一个每次next、一个每次next两次,如果相遇,则成环
     
  • 在无序数组中找最大的K个数:快速排序\\建立一个K个元素的大根堆
     
  • 给定n个数,寻找第k小的数,同时给出时间复杂度:快速排序\\建立一个K个元素的大根堆
     
  • 10w行数据,每行一个单词,统计出现次数出现最多的前100哈希分治法 - 统计海量数据中出现次数最多的前10个IP - 简书
     
  • 10亿条短信,找出前一万条重复率高的:先分片,再尽可能的map-->reduce

不安全网页的黑名单里有100亿个数据,每一个网页的URL最多占用64B。要求实现一种过滤系统,可以根据网页的URL判断是否在这个黑名单中。系统允许有万分之一的失误率。且额外的空间不能超过30GB:一个输入值经过k个哈希函数后,得到了k个值将这个值映射到这个bit数组中,有的就涂黑。所给的题就是将100亿个值依次经过上述过程将bit数组涂黑(置为1)。过后将一个网页的URL经过k个哈希函数得到的k个值对应的bit数组是否被涂黑,若涂黑了就认为在黑名单中。当然如果m的长度不够长则会导致bit数组全被涂黑
 

Bloom Filter跟单哈希函数Bit-Map不同之处在于:Bloom Filter使用了k个哈希函数,每个字符串跟k个bit对应。从而降低了冲突的概率。

布隆过滤器有许多实现与优化,Guava中就提供了一种Bloom Filter的实现。

在使用bloom filter时,绕不过的两点是预估数据量n以及期望的误判率fpp,

排序

  • 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
  • 不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。

二叉树:

  • 二叉排序树:根节点大于左子树,根节点小于右子树。最好的情况下,二叉查找树的查找效率为O(log n);当二叉查找树退化为单链表时,比如,只有右子树的情况,如下图所示,此时查找效率为O(n);所以二叉查找树越是“矮胖”,也就是每层尽可能地被“塞满”(每个父节点均有两个子节点)时,查找效率越高;为了解决二叉查找树退化为单链表时查找效率低下的问题,引入了平衡二叉树
  • 它是二叉搜索树的一种改进,它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树

类型

算法

原理

时间

空间

稳定性

交换排序

冒泡排序

遍历n-1次数组,相邻比较,每次将未排序中最大的元素放到数组尾部

O(n2)

O(1)

稳定

快速排序

设定一个分界值,通过该分界值将数组分成左右两部分;将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。递归重复操作;主要是递归造成的栈空间的使用;平均O(logn),最坏空间复杂度为O(n)

O(nlogn)

O(nlogn)

不稳定

插入排序

直接插入排序

插入排序的工作方式像许多人排序一手扑克牌

O(n2)

O(1)

稳定

希尔排序

缩小增量排序;先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下,效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高(https://segmentfault.com/a/1190000013967025

O(n1.3)

O(1)

不稳定

选择排序

直接选择排序

选择排序(Selection-sort)是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕

O(n2)

O(1)

不稳定

堆排序

  • 大根堆中某个结点的值总是不大于其父结点的值
  • 堆总是一棵完全二叉树。

大根堆的根节点中存放的是最大元素,但是其他节点的排序顺序是未知的。例如,在一个最大堆中,最大的那一个元素总是位于 index 0 的位置,但是最小的元素则未必是最后一个元素。--唯一能够保证的是最小的元素是一个叶节点,但是不确定是哪一个。

基本思想:

  1. 首先将待排序的数组构造成一个大根堆,此时,整个数组的最大值就是堆结构的顶端
  2. 将顶端的数与末尾的数交换,此时,末尾的数为最大值,剩余待排序数组个数为n-1
  1. 将剩余的n-1个数再构造成大根堆,再将顶端数与n-1位置的数交换,如此反复执行,便能得到有序数组

O(nlogn)

O(1)

不稳定

归并排序

二路归并排序

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并

O(nlogn)

O(n)

稳定

多路归并排序

计数排序

计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。定义int[]数组,对于待排序数字集合,数字i直接int[i]位置的值+1。

以上是关于算法实现思路的主要内容,如果未能解决你的问题,请参考以下文章

常用算法Java实现之快速排序

算法--快排

算法--快排

数据结构与算法之深入解析“二叉搜索子树的最大键值和”的求解思路与算法示例

算法复杂性分界函数—多项式

每日一算法|快速排序---第三天