数据结构与算法
逸川先生
Java开发工程师,专注后台开发两年,擅长分布式系统
展开
-
布隆过滤器
本来只是作为笔记的,还是和大家分享下吧 O.O简单写下听课记录,没有具体的实现。如果面试官问道这种分布式抗压问题,可以先扯一下hash分流,如果他说太耗内存,然后可以问他可不可以允许一部分的失误率,如果可以,就可以讲布隆过滤器了。前导知识:进来一个url,现在需要检查它是否在黑名单中存在,存在就返回true假设有个黑名单url有100亿个url,假设每个url有64个字节,...原创 2018-09-14 16:52:57 · 149 阅读 · 0 评论 -
前缀树
1)插入一个字符串到前缀树中 2)查找一个字符串是否在前缀树中存在 3)在前缀树中删除一个自定的字符串 4)查看指定前缀在前缀树中出现过多少次public class C01_TrieTree { public static class TrieTree{ public int end;//字符串结束标志 public int path;//字符串经过的标志 ...原创 2018-03-19 21:16:20 · 251 阅读 · 0 评论 -
认识并查集结构
并查集是1964年别人脑补的一个算法,到证明结束是1989年,这个证明也是够漫长的。并查集的效率非常高,当有N个数据的时候,假设查询次数到了N之后,其时间复杂度仅为O(1)!!并查集使用哈希是来做的,所以节点中并不需要放些什么。FatherMap中key 是当前节点,value是当前节点的父节点。然后是sizeMap,key是当前节点,value是点当前节点的所在集合的节点总个数。getHeadN...原创 2018-03-19 13:18:35 · 180 阅读 · 0 评论 -
最小的路径和
/** 给你一个二维数组,二维数组中的每个数都是正数,要求从左上 角走到右下角,每一步只能向右或者向下。沿途经过的数字要累 加起来。返回最小的路径和。 */public class C02_MinPath { //递归版本--recurtion public static int recMinPath(int[][]matric,int i,int j){ int res = m...原创 2018-03-22 21:57:52 · 365 阅读 · 0 评论 -
最大差值问题
/** 给定一个数组,求如果排序之后,相邻两数的最大差值,要求时 间复杂度O(N),且要求不能用非基于比较的排序(桶排序) 分析:题目要求了不能使用 非基于比较的排序,但是我们可以借用桶排序的概念 假设有N个数,设置N+1个桶,将数放到桶中,最大值放到最后一个桶, 最小值放到第一个桶,故中间一定存在一个空桶(至少) 设计空桶的目的是否定最大差值来之一个桶内,而不是说最大差值一定在空...原创 2018-03-05 22:41:38 · 978 阅读 · 0 评论 -
归并排序
归并的思想其实不难,就是假设有两个有序数组a,b,现在需要把它合并成一个有序的数组,要是使用快排或者其他的排序(除了桶排序)理论值就达到了O(N*logN)了,假如我建立一个数组c,长度是他们两个数组的和,然后从两个数组a,b他们的第一个值来比较,将小的放到c的前面,然后指针下移一个位置,再拿出两个数组前面的较小值放到c,,,这样就使用了O(N)的时间复杂度完成了排序。剩下的就是递归的问题了,这个...原创 2018-03-18 19:09:19 · 164 阅读 · 0 评论 -
时间复杂度
常数时间的操作:一个操作如果和数据量没有关系,每次都是固定时间内完成的操作,叫做常数操作。时间复杂度为一个算法流程中,常数操作数量的指标。常用O来表示。具体来说,在常数操作数量的表达式中,只要高阶项,不要低阶项,也不要高阶项的系数,剩下的部分如果记为f(N),那么时间复杂度为O(f(N))。评价一个算法流程的好坏,先看时间复杂度的指标,然后再分析不同数据样本下的实际运行时间,也就是常数项时间mas...原创 2018-02-25 13:33:13 · 270 阅读 · 0 评论 -
插入排序
插入排序的时间复杂度是N^2。插入排序有N-1趟排序组成,对于i=1到N-1趟,插入排序保证从位置0到位置i的元素处于排好的状态。从位置j开始与前一个比较,符合条件的就交换,一直到不符合条件。加个例子:原始数组是34,8,64,51,32,21一趟:8,34,64,51,32,21二趟:8,34,64,51,32,21三趟:8,34,51,64,32,21四趟:8,32,34,51,64,21五趟...原创 2017-12-02 23:33:31 · 167 阅读 · 0 评论 -
对数器的概念和使用
对数器在无法进行数据校验的情况下起着极为重要的作用,尤其是数据量大的时候。这里使用简单的冒泡排序进行演示/** 冒泡排序 并使用对数器进行校验 对数器的概念和使用 0)有一个你想要测的方法a, 1)实现一个绝对正确但是复杂度不好的方法b, 2)实现一个随机样本产生器 3)实现比对的方法 4)把方法a和方法b比对很多次来验证方法a是否正确。 5)如果有一个样本使得比对出错,打印样本...原创 2018-02-24 17:34:49 · 760 阅读 · 1 评论 -
堆排序
想学会堆排序,就应该先理解堆结构。堆分为大根堆和小根堆,大根堆就是所有的根节点都比他的子节点都要大,小根堆同理。我们进行堆排序的时候,其实并不是真的要用到二叉树(完全二叉树),而只是借用这个知识来理解,可以将一个数组想象成一棵树。例如i节点的父节点就是(i+1)/2,i节点的左子节点就是i*2+1,右子节点就是i*2+2。heapInsert:将数组的0到1位置的数变成一个大根堆,然后...原创 2018-03-02 16:05:24 · 265 阅读 · 0 评论 -
复制含有随机指针节点的链表
【题目】 一种特殊的链表节点类描述如下:public class Node { public int value; public Node next; public Node rand; public Node(int data) { this.value = data; }}Node类中的value是节点值,next指针和正常单链表中ne...原创 2018-03-09 23:27:04 · 237 阅读 · 0 评论 -
拼接字符串,使其具有最低字典序
* 给定一个字符串类型的数组strs[],找到一种拼接方式,使得把所 * 有字 符串拼起来之后形成的字符串具有最低的字典序。 * 贪心策略。import java.util.Arrays;import java.util.Comparator;public class C02_LowestLexicography { //贪心策略 public static String lowestS...原创 2018-03-19 22:51:02 · 335 阅读 · 0 评论 -
切金条问题
一块金条切成两半,是需要花费和长度数值一样的铜板的。比如 长度为20的 金条,不管切成长度多大的两半,都要花费20个铜 板。一群人想整分整块金 条,怎么分最省铜板? 例如,给定数组{10,20,30},代表一共三个人,整块金条长度为 10+20+30=60. 金条要分成10,20,30三个部分。 如果, 先把长 度60的金条分成10和50,花费60 再把长度5...原创 2018-03-20 19:59:24 · 1027 阅读 · 0 评论 -
项目最大收益(贪心问题)
输入: 参数1,正数数组costs 参数2,正数数组profits 参数3,正数k 参数4,正数m costs[i]表示i号项目的花费 profits[i]表示i号项目在扣除花 费之后还能挣到的钱(利润) k表示你不能并行、只能串行的最多做k个项目 m表示你初始的资金 说明:你每做完一个项目,马上获得的收益,可以支持你去做下一个 项目。 输出: 你最后获得的最大钱数...原创 2018-03-20 21:20:13 · 2641 阅读 · 0 评论 -
非递归随机快排
之前写过递归形式的随机快排,但是发现效率并不理想,今天正好复习算法,就索性将递归的改为非递归的。任何递归形式的方法都是系统压栈的,而我们可以自己压栈,也就是说所有的递归都可以改为非递归方法。同样,先放出荷兰国旗问题:https://blog.csdn.net/qq_38238041/article/details/79250087,懂了这个才有学习快排的基础递归形式的快排就不写了,可以...原创 2018-08-16 11:06:34 · 236 阅读 · 0 评论 -
两个单链表相交的一系列问题(成环,不成环)
【题目】 在本题中,单链表可能有环,也可能无环。给定两个 单链表的头节点 head1和head2,这两个链表可能相交,也可能 不相交。请实现一个函数, 如果两个链表相交,请返回相交的 第一个节点;如果不相交,返回null 即可。 要求:如果链表1 的长度为N,链表2的长度为M,时间复杂度请达到 O(N+M),额外 空间复杂度请达到O(1)。我们将问题分为四个部...原创 2018-04-10 23:06:05 · 1042 阅读 · 0 评论 -
深搜解决倒油问题 --面向过程
/** * 从盛12斤油(a桶)的桶中倒出6斤油来,可是手边只有盛8斤油(b桶) * 和盛5斤油(c桶)的两个桶,问如何操作才能将6斤取出来呢? * 面向过程方法倒油: */public class PoulOil2 { public static int max[] = new int[] { 12, 8, 5 };// 桶的最大容量 public static final int...原创 2018-03-28 12:23:49 · 893 阅读 · 0 评论 -
如何反转单向链表和双向链表( 空间复杂度O(1) )
反转链表,最简单的就是使用栈了,放进栈里然后拿出来,但这样的操作使用的空间复杂度是O(N)..其实可以做到空间复杂度是O(1)的。public class C08_RevolveLinked1 { // 单向链表 public static class Node { int value; Node next; public Node(int value) { this.va...原创 2018-04-01 21:11:12 · 2691 阅读 · 0 评论 -
拓扑排序算法(TopologySort)
拓扑排序算法 适用范围:要求有向图,且有入度为0的节点,且没有环 1.将图中的所有节点全部记录到HashMap,入度为零的节点添加到zeroInQueue 2.建立一个集合用来存放结果 3.从zeroInQueue中弹出一个,遍历她的子节点 4.将其子节点入度减一 5.如果这个子节点的入度为零了,就将其放入到zeroInQueue中图的表示和生成见:点击打开链...原创 2018-03-26 15:39:22 · 2833 阅读 · 0 评论 -
深度优先遍历图(DFS)
流程: 1,利用栈实现 2,从源节点开始把节点按照深度放入栈,然后弹出 3,每弹出一个点,把该节点下一个没有进过栈的邻接点放入栈 4,直到栈变空图的表示和生成见:点击打开链接import java.util.HashSet;import java.util.Set;import java.util.Stack;public class DFS { pub...原创 2018-03-26 15:36:41 · 609 阅读 · 0 评论 -
非递归 宽度优先遍历图(BFS)
流程: 1,利用队列实现 2,从源节点开始依次按照宽度进队列,然后弹出 3,每弹出一个点,把该节点所有没有进过队列的邻接点放入队 列 4,直到队列变空图的表示和生成见:点击打开链接import java.util.HashSet;import java.util.LinkedList;import java.util.Queue;public clas...原创 2018-03-26 15:31:21 · 626 阅读 · 0 评论 -
生成图、表示图的一个强大方法
图的表示一般是可以使用邻接表、邻接矩阵……来表示的,网上大把,这里介绍的是一种更为强大的方式,基本上可以应对所有的关于图的算法,例如拓扑排序、深搜、广搜、Kruskal、Prim、Dijkstra。创建图的时候是传递一个二维数组过来,matrix[i][0]是权重,matrix[i][1]是起始点的值,matrix[i][2]是终止点的值,最后返回一张图。public class GraphGen...原创 2018-03-26 15:26:49 · 3087 阅读 · 0 评论 -
归并排序及其应用
归并排序(英语:Merge sort,或mergesort),是建立在归并操作上的一种有效的排序算法,效率为O(n*log n)} 。1945年由约翰·冯·诺伊曼首次提出。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。import java.util.Arrays;import java.util.Random;public cla...原创 2018-03-30 14:33:53 · 456 阅读 · 0 评论 -
活动安排问题2
/** * 活动安排问题 * 一些项目要占用一个会议室宣讲,会议室不能同时容纳两个项目 * 的宣讲。 给你每一个项目开始的时间和结束的时间(给你一个数 * 组,里面 是一个个具体的项目),你来安排宣讲的日程,要求会 * 议室进行 的宣讲的场次最多。返回这个最多的宣讲场次。 */import java.util.Arrays;import java.util.Comparator;...原创 2018-03-20 22:08:59 · 281 阅读 · 0 评论 -
在行列都排好序的矩阵中找数
题目看图:很简单的一个题目,好像剑指offer里面有个一样的题。因为题目给定的条件十分特殊,行列都是排好序的,所以只需要从右上或者左下角开始找,假设从右上角(A点)开始找,根据排好序的题设,可以知道,如果要找的数B大于A则B向下走一步在比较,否则向左走一步在比较,这样一直走到边界。下面看代码:public class C08_FindNumInSortMatrix { public static...原创 2018-03-09 20:13:19 · 169 阅读 · 0 评论 -
之字形打印矩阵
题目看图:这个题目给人的第一感觉就是,这个出题人脑子又泡吧。之字形打印?太无聊了,其实这个是一种宏观调度思想的实例。我前面也有写过两个相关题目:转圈打印,旋转矩阵讲讲思路:如果限制自己的思路,这个题目是十分难以实现的,和前面两个题目一样,需要两个点来控制走向A(aR,aC),B(bR,bC)(行,列).A点只向右走,当走到最右点的时候,就向下走,B点向下走,当到达最下点的时候就向右走,这样就形成了...原创 2018-03-09 19:33:15 · 466 阅读 · 0 评论 -
左神算法课堂系列--纸条折痕问题
算法敏感度的训练【题目】请把一段纸条竖着放在桌子上,然后从纸条的下边向上方对折1次,压出折痕后展开。此时折痕是凹下去的,即折痕突起的方向指向纸条的背面。如果从纸条的下边向上方连续对折2次,压出折痕后展开,此时有三条折痕,从上到下依次是下折痕、下折痕和上折痕。给定一个输入参数N,代表纸条都从下边向上方连续对折N次,请从上到下打印所有折痕的方向。例如:N=1时,打印:downN原创 2018-02-04 14:12:36 · 1032 阅读 · 0 评论 -
左神算法课堂系列--数组划分最大绝对值之差问题
算法思维的锻炼【题目】已知一个整型数组arr,数组长度为size且size大于2,arr有size-1种可以划分成左右两部分的方案。比如:arr = {3, 2, 3, 4, 1, 2}第1种划分左部分为[3],右部分为[2, 3, 4, 1, 2]第2种划分左部分为[3, 2],右部分为[3, 4, 1, 2]第3种划分左部分为[3, 2, 3],右部分为[4,原创 2018-02-03 23:08:27 · 732 阅读 · 0 评论 -
牛客网直通BAT面试算法精讲课优惠码
优惠码:AGkLFZG链接:http://www.nowcoder.com/courses/1?coupon=AGkLFZG原创 2018-02-01 19:44:41 · 441 阅读 · 0 评论 -
素数筛选法简单介绍
之前写这个素数筛选法没写好,表示抱歉,现在改过来了。通常情况下,我们会想到这样写一个素数的筛选方法 用来筛选1-100的素数 public static void main(String[] args) { for(int i = 2;i <= 100;i++){ if(prime(i)){ System.out.pri原创 2017-09-24 09:30:20 · 638 阅读 · 0 评论 -
HDOJ2084 数塔(动态规划入门)
题目链接:数塔(动态规划入门)动态规划(dp),是算法中十分常用的一个技巧,而数塔通常作为入门级别的题目来解释分析:题目要求我们从顶向下找出一条结点数和最大的路径,但只需要最大路径的值。每一步只能走到相邻的结点。然后我们自然就会想真的每一步都走一遍,然后比较结果大小但是这样的效率显然是达不到要求的,然后再想办法做优化既然自顶向下,那么我们可以再做一个一样的数组7原创 2017-11-19 18:59:37 · 735 阅读 · 0 评论 -
算法设计之补零递归法(统计数字问题)
问题:给定一个数N求从1到N的这N个数中0,1,2,3,4,5,6,7,8,9这10个数字出现的次数。注意,所有的数字没有前导的0。 如6要写成6,而不是006 ,06这种形式思路1:也就是最简单最容易实现的做法,但是当n很大的时候,运行时间会变得十分长import java.util.Scanner;public class CountPage { private stat原创 2017-10-24 21:41:22 · 1411 阅读 · 0 评论 -
HDOJ2059_龟兔赛跑(动态规划DP)
Problem Description据说在很久很久以前,可怜的兔子经历了人生中最大的打击——赛跑输给乌龟后,心中郁闷,发誓要报仇雪恨,于是躲进了杭州下沙某农业园卧薪尝胆潜心修炼,终于练成了绝技,能够毫不休息得以恒定的速度(VR m/s)一直跑。兔子一直想找机会好好得教训一下乌龟,以雪前耻。最近正值HDU举办50周年校庆,社会各大名流齐聚下沙,兔子也趁此机会向乌龟发起挑战。虽然乌龟深知获胜原创 2017-10-27 22:46:17 · 316 阅读 · 0 评论 -
贪心算法--活动安排
贪心算法是指在对问题求解时候,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。 贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。 所以对所采用的贪心策略一定要仔细分析原创 2017-10-28 15:28:48 · 394 阅读 · 0 评论 -
程序员代码面试指南--设计一个具有getMin功能的栈
/* 设计一个有getMin功能的栈 【题目】 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回 栈中最小元素的操作。 【要求】 1.pop、push、getMin操作的时间复杂度都是O(1)。 2.设计的栈类型可以使用现成的栈结构。在设计上我们使用两个栈,一个栈用来保存当前栈中的元素,其功能和一个正常的栈没有区别,这个栈记为stackData;另一个栈用于保存每原创 2018-02-04 16:21:06 · 206 阅读 · 0 评论 -
程序员代码面试指南--由两个栈组成的队列
/** 由两个栈组成的队列 【题目】编写一个类,用两个栈实现队列,支持队列的基本操作(add、pollpeek)。 栈的特点是先进后出,而队列的特点是先进先出。我们用两个栈正好能把顺序反过来实现类似队列的操作。 具体实现上是一个栈作为压入栈,在压入数据时只往这个栈中压入, 记为stackPush;另一个栈只作为弹出栈,在弹出数据时只从这个栈弹出,记为stackPop。 因为数据压入原创 2018-02-04 22:38:40 · 195 阅读 · 0 评论 -
程序员代码面试指南--生成窗口最大值数组
/** 生成窗口最大值数组 【题目】 有一个整城数组arr和一个大小为w的窗口从数组的最左边滑到最右边,容口每次向右边滑一个位置。 如果数组长度为n,窗口大小为w,则一共产生n-w+1个窗口的最大值。 请实现一个函数。 -输入:整型数组arr,窗口大小为w。 -输出:一个长度为n-w+1的数组res,res[]表示每一种窗口状态下的最大值。 *//** 假设遍历到arr[i],...原创 2018-02-10 16:10:25 · 212 阅读 · 0 评论 -
设计RandomPool结构
设计RandomPool结构 【题目】 设计一种结构,在该结构中有如下三个功能: insert(key):将某个key加入到该结构,做到不重复加入。 delete(key):将原本在结构中的某个key移除。 getRandom(): 等概率随机返回结构中的任何一个key。 【要求】 Insert、delete和getRandom方法的时间复杂度都是O(1)im...原创 2018-03-15 20:49:47 · 897 阅读 · 1 评论 -
顺时针旋转矩阵九十度
/** * 将一个矩阵(一定是正方形)顺时针旋转九十度 */public class C06_RotateMatrix { public static void rotateMatrix(int[][]arr){ if(arr==null || arr.length==0 || arr[0].length==0){ return ; } int a = 0;//左上角,列...原创 2018-03-08 21:21:24 · 1565 阅读 · 0 评论 -
使用二分对插入排序进行优化
/* * test经过二分进行优化的插入排序(在工程上的基本数据类型排序其实当数据量少的时候是使用二分的) * 插排时间复杂度是O(N*N) * 经过二分的优化可以达到O(N*log(N)) * 插入排序具有 稳定性(假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中) */import java.util.Arrays;i...原创 2018-03-15 14:10:33 · 337 阅读 · 0 评论