data structure && algorithm
文章平均质量分 54
ForABiggerWorld
这个作者很懒,什么都没留下…
展开
-
红黑树
完全参考《Algorithm》edition IV中的相应章节通过求树的高度来实现对implementation的测试 2-3树是一种平衡树,通过自下而上地添加一条数据,往上调整来实现树的平衡,而红黑树就是2-3树的一种实现(把red edge放平就是一棵平衡的2-3树),在红黑树中从根节点到叶子节点的距离计算的是黑色的edge,以此为了维持平衡,在修正红黑树的前后要保证不影响各个支路...原创 2017-03-03 21:53:06 · 228 阅读 · 0 评论 -
2pointer + 双端队列 计算区间max-min在一定范围的子数组个数
维护2个双端队列A,B。A用来求滑动窗口的最大值,B最小值(这里的窗口大小没有限制)假设我们窗口左边从第1位开始,右边扩到i位置时max-min大于给定的范围,那我们继续扩下去也没有必要,因为:窗口扩张后,当前窗口的max只会比之前窗口的max大,min比之前窗口的min小。那这时就可以求出窗口左边以第一位置开始的valid窗口的个数,就是窗口的宽度接着左边从第一位移到第二原创 2017-05-27 21:04:23 · 488 阅读 · 0 评论 -
子数组问题
子数组问题因为是连续的,所以有个套路:当以index为i结尾时,怎样这样。。。,index为i+1的时候又怎么求出来来看几个例子把:算法模型就是最大子数组和,用DP,而dp[i]的意义就是到i位置为止,以a[i]结尾(a为原始数组)的最大子数组和这里无非就是用2个数组分别从左右两边求,然后再遍历一遍2个数组这个题是子数组问题的一个算法原型:先原创 2017-05-10 22:03:33 · 271 阅读 · 0 评论 -
LCS相关问题
2个字符串的匹配用KMP2个字符串的最长公共子序列,最长公共子串用DP一个字符串的最长回文子序列(可以不连续):求该字符串与reverse字符串的最长公共子序列一个字符串的最长回文子串(连续):无法用该字符串与reverse字符串的最长公共子串来求,比如abcXcba。用的是Manacher算法原创 2017-04-27 19:17:58 · 299 阅读 · 0 评论 -
KMP
next数组求解next数组含义:next[i]表示i位置前最长的相同的前缀和后缀(前缀不能包括最后一个数,后缀不能包括第一个数)next[0]规定为-1假设在求next[i]的时候,i之前的next已经求出来了,那么过程如下:根据这个我们就可以写出代码pos是要求的当前的next的indexcn是要求pos时当前要考虑的next[cn]原创 2017-04-27 21:27:18 · 452 阅读 · 0 评论 -
一些链表问题
如果是用数组,或者栈保存数据,那没的说,但是题目要求空间O(1),那就先把一半的链表逆序,OK除了普通的指针指向下一个Node,还指向了一个随机的Node,那可以1. 用HashTable记录对应关系,先复制一遍,再把random指向关系搞定2. 遇到没有建立的,就递归调用,return前加到HashSet里面3. 复制的时候加在原链表的原创 2017-05-28 17:31:38 · 424 阅读 · 0 评论 -
快速排序partition过程常见的两种写法
这里不详细说明快速排序的原理,具体可参考here快速排序主要是partition的过程,partition最常用有以下两种写法第一种:12345678910111213int mypartition(vectorint>&arr,i转载 2017-06-01 08:41:35 · 1409 阅读 · 0 评论 -
二叉树相关问题
前序,中序非递归比较容易前序:先一直压左孩子,每次压栈的时候就打印,没有左孩子可压,就出栈,同时把右孩子压栈,继续一直压左孩子中序:先一直压左孩子,没有左孩子可压,就出栈,出栈的时候打印,同时把右孩子压栈,继续一直压左孩子而后续因为要把左右孩子都遍历完了才能打印当前节点node,而又不能通过node把左右孩子联系起来(前中序都有当前节点在栈中维持node.left,node.r原创 2017-06-04 17:15:34 · 384 阅读 · 0 评论 -
遍历二叉树的神级方法--Morris 遍历
Morris 遍历可以做到O(N)的时间复杂度,O(1)的空间复杂度有以下几个点先要了解1. 树的节点有很多的left,right指向null,Morris利用了这些指针2. 遍历树过程中:第一次遇到某个节点就输出是前序遍历,第二次遇到再输出是中序遍历,第三次遇到再输出是后续遍历原创 2017-06-08 20:50:36 · 1487 阅读 · 0 评论 -
查找 Hash VS Tree
Hash是空间换时间,设计的好的话查找效率高但是相比于树,不能查找最大最小值,区间范围值Hash和Tree在删除元素也有区别,Hash是懒删除另外:Hash的开放地址容易聚集,平方探测一定限度能减弱聚集现象,但是可能会出现差不多插的位置拉链法的缺点是存储效率低原创 2017-05-23 11:49:20 · 291 阅读 · 0 评论 -
DP 问题
DP是弄清楚计算方向后的记忆化搜索DP 还要往前跳 因为DP过程遇到(直接归0, 不是平稳的1. 递归2. DP VS DFSO(N2), O(N3)那个stock是不是也可以这样优化?只用求有限个?递归--记忆化--状态转移方程--状态转移方程化简如果DP过程有枚举过程,看一下原创 2017-06-25 22:35:22 · 358 阅读 · 0 评论 -
GEOMETRIC APPLICATIONS OF BSTS
先看个基础的问题:1. 1d range search:(对应到数据库就是range find)如果只要查一次,遍历一次就好了,但是如果要查很多次呢(每次要查的范围不一样)?如果待搜索的数据空间量还在变化呢?这时,普通的brute-force就不行了,解决方案之一是把数据加到BST中,计算rank(比该节点的值小的节点有多少个)原创 2017-09-17 13:02:03 · 377 阅读 · 0 评论 -
BFPRT算法
背景:求无序数组中第k小的数一般的思路都很多,sort,Heap,Partion需要说明的是Partion并不能保证O(N)的最坏复杂度,因为中心枢纽是随机选的,不能保证后续的递归量分的均匀,而本文要介绍的方法是可以做到保证O(N),思路类似于Partion,但是区别,也是关键在于中心枢纽的选择,具体步骤如下:费很大的劲来求king这个枢纽的目的在于减小后续递归原创 2017-04-27 21:39:25 · 320 阅读 · 0 评论 -
矩阵 若干问题
将问题先分解到1维数组的情况,即求一维数组的子数组的最大和对于这个算法原型:维护一个从0开始累加的cur的变量,每当cur的值为负数,就把cur清零继续累加其基本的原理是最优的结果的任意前缀数组的和一定不会小于0,因为如果小于0的话,把这个前缀丢掉不就可以获得一个更大的和了吗?回到原题目,现在就是要把二维数组转化为1维的情况,那我们就遍历矩阵的上下边界或者左右边界,然后把这个边原创 2017-05-15 21:56:30 · 292 阅读 · 0 评论 -
字符串表达式求值
当然可以转换为后缀表达式求,也可以一步步将问题分解,如下:原创 2017-05-16 21:56:11 · 531 阅读 · 0 评论 -
复杂链表的复制
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)思路:刚开始想到的是很直接的想法,先按照next完全clone一遍,并放到一个数组里面,然后对原链表做处理,用Map储存每个Node对应的index,然后在clone出来的链原创 2017-04-17 20:05:27 · 291 阅读 · 0 评论 -
优先队列 与 堆
(1)堆是优先队列的一种实现,核心的方法是swim和sink(2)堆与二叉查找树不同,堆的父节点比子节点都大(3)优先队列的应用场合:需要处理有序的元素,但不一定要求他们全部有序,或是不一定要一次就将他们排序Java实现如下:/* * 很简单的最大优先队列,里面存储的是int */public class MaxPQ { public int N = 0;原创 2016-10-20 16:47:21 · 626 阅读 · 0 评论 -
判断单链表是否存在环 && 判断两链表是否相交
给定一个单链表,只给出头指针h:1、如何判断是否存在环?2、如何知道环的长度?3、如何找出环的连接点在哪里?4、带环链表的长度是多少? 解法:1、对于问题1,使用追赶的方法,设定两个指针slow、fast,从头指针开始,每次分别前进1步、2步。如存在环,则两者相遇;如不存在环,fast遇到NULL退出。2、对于问题2,记录下问题1的碰转载 2017-04-04 19:25:24 · 265 阅读 · 0 评论 -
矩阵快速幂
小易拥有一个拥有魔力的手环上面有n个数字(构成一个环),当这个魔力手环每次使用魔力的时候就会发生一种奇特的变化:每个数字会变成自己跟后面一个数字的和(最后一个数字的后面一个数字是第一个),一旦某个位置的数字大于等于100就马上对100取模(比如某个位置变为103,就会自动变为3).现在给出这个魔力手环的构成,请你计算出使用k次魔力之后魔力手环的状态。 输入描述:输入数据包括两行:原创 2017-04-12 19:40:06 · 733 阅读 · 0 评论 -
动态规划 && 矩阵快速幂
先看题把:对于斐波拉契经典问题,我们都非常熟悉,通过递推公式F(n) = F(n - 1) + F(n - 2),我们可以在线性时间内求出第n项F(n),现在考虑斐波拉契的加强版,我们要求的项数n的范围为int范围内的非负整数,请设计一个高效算法,计算第n项F(n-1)。第一个斐波拉契数为F(0) = 1。给定一个非负整数,请返回斐波拉契数列的第n项,为了防止溢出,请将结果Mod原创 2017-04-13 15:56:26 · 636 阅读 · 0 评论 -
经典动态规划2-----Map记录
从递归可以优化到记忆化搜索,直接看题:对于一个只由0(假)、1(真)、&(逻辑与)、|(逻辑或)和^(异或)五种字符组成的逻辑表达式,再给定一个结果值。现在可以对这个没有括号的表达式任意加合法的括号,返回得到能有多少种加括号的方式,可以达到这个结果。给定一个字符串表达式exp及它的长度len,同时给定结果值ret,请返回方案数。保证表达式长度小于等于300。为了原创 2017-04-18 19:14:06 · 455 阅读 · 0 评论 -
汉诺塔问题
什么是汉诺塔:https://zh.wikipedia.org/zh-hans/%E6%B1%89%E8%AF%BA%E5%A1%94汉诺塔是理解递归的绝佳例子,最佳的方案一定是按照以下三步来的:(1)先把from的前n-1个盘子放到mid柱子上,(2)然后把from的最后一个放到to最低端(3)把mid的n-1个放到to上面(因为to下面是最大的,所以完全可以忽略他们原创 2017-04-14 20:55:35 · 726 阅读 · 0 评论 -
经典动态规划1
经典的DP题,面试的时候直接用DP写就好了,不用从暴力递归,到数据记录,再到枚举糙动态规划,DP 是递归时候 发现的用空间换时间的方法, 比如LCS:要求左上,左边,上边,再做决策,然后这三者都是有重复计算的,所以考虑用DP把结果存下来,下次重复利用用DP的时候,先明确一点:dp[i][j]表示的是什么!然后想怎么根据之前的计算决策当前!(决策的方案可以先从最简单的情况入手(比原创 2017-04-16 14:33:11 · 465 阅读 · 0 评论 -
Hashing - Hard Version
Given a hash table of size NNN, we can define a hash function . Suppose that the linear probing is used to solve collisions, we can easily obtain the status of the hash table with a given sequence o原创 2017-05-13 22:22:11 · 934 阅读 · 0 评论 -
完全二叉树的节点个数
给定一棵完全二叉树的头节点 head,求其中的节点个数。原创 2017-05-15 21:57:18 · 613 阅读 · 0 评论 -
前缀树 / 字典树 / Trie树
使用Trie树的一个好处是在建树的过程中就完成了查找的过程这里就是2种情况:在插入某个字符串的时候,1. 走完了别人的路,自己还没插入完2. 自己走完了,但是还在别人的路上原创 2017-05-15 21:23:59 · 305 阅读 · 0 评论 -
逆序栈
在这之前先看一个算法原型:在不用其他数据结构的情况下,删除栈底的数如果可以另外申请一个栈,那就很naive,但是题目要求不能,但是我们利用递归过程系统自动为我们形成的栈有了上述的这样一个函数,原题的逆序栈就可以调用这个函数了原创 2017-05-16 21:51:53 · 512 阅读 · 0 评论 -
算法系列——四种最短路算法:Floyd,Dijkstra,Bellman-Ford,SPFA
https://zhuanlan.zhihu.com/p/33162490 Floyd一种基于动态规划的多源最短路算法private void floyd() { for (int k = 0; k < n; k++) { for (int i = 0; i < n; i++) { for (in...原创 2018-08-17 11:51:16 · 445 阅读 · 0 评论