
算法
文章平均质量分 71
水墨之白
悟已往之不谏,知来者之可追!
展开
-
什么是尾递归?
求阶乘: n! def fact(n): if n==1: return 1 return n * fact(n - 1) 理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰 在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,...原创 2018-09-01 15:50:58 · 1674 阅读 · 0 评论 -
LRU缓存设计
设计一个LRU算法(最近最少移除)来实现缓存 思路: 使用双向链表 + HashMap 实现 采取尾插法,未达到存储上限就每次在加入到链表尾部 访问链表节点,就将对应链表节点移到尾部,保持尾节点数据最新 链表长度达到上限就删除头节点 代码: public class LRUCache { private Node head; private Node end; //...原创 2019-09-18 19:40:05 · 211 阅读 · 0 评论 -
理解Raft算法
引言 一个有意思的问题: 甲乙两人轮流在一张圆桌上平放黑白围棋子,每次放一子,棋子不许重叠, 谁先没有地方放就输。请问怎样放才能赢? 答案: 先行者必胜 三种不同的思维方式: 假如桌子只有一个围棋子那么大 假如桌子无限大,先行者先占住圆心,由于圆是对称图形,所以只要对手还能找到位置放,你总能在对称的另一面找到位置放 一个圆中可画单数个直径相等且互切的小圆(即最后一粒棋子一定是单数) 三种不同...原创 2019-09-11 20:58:52 · 719 阅读 · 0 评论 -
搞懂时间和空间复杂度,看懂这篇文章即可
复杂度分析是整个算法学习的精髓,只要掌握了它,数据结构和算法的内容基本上就掌握了一半了。 1. 什么是复杂度分析 ? 数据结构和算法解决是 “如何让计算机更快时间、更省空间的解决问题”。 因此需从执行时间和占用空间两个维度来评估数据结构和算法的性能。 分别用时间复杂度和空间复杂度两个概念来描述性能问题,二者统称为复杂度。 复杂度描述的是算法执行时间(或占用空间)与数据规模的增长...转载 2019-06-04 16:44:52 · 794 阅读 · 0 评论 -
非比较排序—计数排序
思路: 空间换时间 非比较排序 先统计,再遍历输出 求出待排序数组最大值与最小值的差值,加1作为统计数组的长度 遍历原数组,进行统计,例:原数组值为2,将countArr位置的value加1(初始value=0) 遍历统计数组,按照下标值输出,例:index:5 value:3 ,输出三次5 按照上述方法进行的计数排序,是不稳定的排序,优化思路: 求出统计数组下标值在原数组位置 这句话有点难...原创 2019-06-03 15:40:06 · 194 阅读 · 0 评论 -
归并排序
归并排序,稳定性排序 时间复杂度O(nlogn) 思路: 分治思想,将数组切分成左右两部分,递归切分,当只剩下一个元素时,就是有序集合 然后进行合并,两边集合进行比较,设置左右指针和临时数组,较小的数放入临时数组,同时指针从左向右移动一位。 代码: public class MergeSort { public static void main(String[] args) { ...原创 2019-06-03 14:11:55 · 155 阅读 · 0 评论 -
二分查找及其优化
思路: 在有序数组中,找到数组中间位置数据和目标数据比较,大于目标数据,在左边继续递归,小于目标数据在右边继续递归 二分查找时间复杂度O(log n),每次过滤一半数据,注意大数溢出情况 理解二分查找对理解树的遍历很有帮助 代码: public class BinarySerach { private static int binarySerach(int arr[], int targ...原创 2019-06-03 14:07:14 · 649 阅读 · 0 评论 -
堆排序
思路: 首先构建大根堆: 数组逻辑上看成堆,父节点大于任意子节点的二叉树 父子节点关系:子:index 父:(index - 1) / 2 step1: 构建大根堆的时候,如果子节点大于父节点,交换双方位置,进行上浮,直到子节点小于等于父节点 or 到达根节点 step2: 堆顶和最后一个数交换,size减一,然后维持大根堆,堆顶进行下沉,直到父节点大于等于左右子节点 or 选出左右子节点最大值...原创 2019-04-22 23:59:11 · 132 阅读 · 0 评论 -
快速排序
思路: 分治思想 1. 选取一个元素作为主元,小于等于主元元素放左边,大于主元元素放在右边,重复递归调用 2. 上面一次只能搞定一个数的位置,如果数组中重复出现多次某个数值,建议使用下面方法 3. 选取一个元素作为主元,小于主元元素放左边,等于主元元素放中间,大于主元元素放在右边,重复递归调用 4. 快排的时间复杂度为O(nlogn) 最坏情况为O(n^2) 空间复杂度为O(logn) Pytho...原创 2019-04-22 23:23:10 · 132 阅读 · 0 评论 -
一致性hash算法原理及其代码实现
小知识 在分布式项目中,分库分表一般使用取模算法,比如一个电商项目,用户量很大,那么可以使用用户ID进行hash取模,进行分表,但是有个严重问题,如果分表数目没有预估好,随着用户量不断增大,单表数据量过大,这个时候需要扩容,改变分表数,数据迁移的难度就太大了。 一致性hash算法就可以解决分布式情况下动态扩容问题。 原理 1.先构造一个长度为2^32的整数环(范围[0, 2^32-1]); 2.根...原创 2018-12-10 20:32:08 · 397 阅读 · 0 评论 -
bitMap原理及实战
小知识 在实际项目中,我们经常需要聚合统计,比如统计一个年龄在20-30,喜欢看技术书籍,喜欢听音乐,喜欢宅在家的程序员等等一系列标签的用户。 如果使用mysql求并集,首先语句随着标签变长而变长,其次聚合,分组,去重严重影响语句性能。这种情况如何解决? 比如现在比较火的面试题,在10亿整数中找出100个重复的数,或者任意给定一个整数,判断是否在这个10亿数中。 bitMap原理 bitMap...原创 2018-12-13 20:34:08 · 708 阅读 · 0 评论 -
基本排序及其优化——冒泡 选择 插入
话不多说,小知识先走一波 小知识 如何不使用额外变量完成数组不同位置值的交换? 代码: /** * 不使用第三个变量,交换数组不同的数值 * @param arr * @param x * @param y */ public static void swap(int arr[], int x, int y) { arr[x...原创 2018-12-08 11:09:48 · 205 阅读 · 0 评论 -
理解动态规划算法
一只青蛙一次可以在台阶跳一步或者两步,那么n级台阶青蛙有多少种跳法? 思路: 假设台阶为10级 青蛙最后一次跳上第10级台阶,只能从第9级或者第8级 这个问题就演变为 f(10) = f(9) + f(8) 依次类推f(9) = f(8) + f(7),一直到f(3) = f(2) + f(1) = 2 + 1 = 3种,即跳上3级台阶要3种方法 总结公式:f(n) = f(n-1) + f(...原创 2019-09-20 15:08:30 · 270 阅读 · 0 评论