随笔分类 - 算法与数据结构
摘要:如果定义一个数组,每一个字符都和一个索引相对应,那么对元素的查找操作是O(1)级别的 这个数组就称作哈希表,而将字符转化为对应的索引的方法称为哈希函数,转化以后就可以只在哈希表上操作而无需关注原始的字符 哈希函数的设计思路 哈希表一个很重要的问题是,很难保证每一个元素通过哈希函数的转换,都能对应不同
阅读全文
摘要:2-3树 2-3树满足二分搜索树的基本性质,中间节点的值大于左子树,小于右子树 但是,其节点可以存放1个元素或者2个元素,即每个节点有2个孩子或者3个孩子,分别称为2节点和3节点 2-3树是一种绝对平衡树,任何时候任何节点的子树高度都一样,即要么是叶子节点,要么同时有左(中)右孩子 2-3树如何维持
阅读全文
摘要:二分搜索树最大的问题是,在存储有序的数组时会退化成链表,性能大大降低。需要在现有二分搜索树的基础上添加一些机制,使得其能维持平衡二叉树 而AVL树是最早的自平衡二分搜索树,可以自动平衡的分布节点,避免退化成链表 平衡二叉树 完全二叉树、满二叉树都是平衡二叉树,其所有叶子节点的高度相差不超过1,平衡度
阅读全文
摘要:并查集,又称Union Find,和之前的树结构不同,并查集的指针由孩子指向父亲 常用于解决连接问题,比如网络中节点间的连接状态 对一组数据,并查集主要支持合并和查询两个动作,unionElement(p, q)和isConnected(q, p) 数组实现并查集(Quick Find) 效率低,不
阅读全文
摘要:Trie,又称字典树、前缀树,是一种N叉树 Trie是一种专门为字典设计的数据结构,通常只用来处理字符串;而之前的Map更适合称为映射而不是字典,因为其存储的对象不一定是字符串 如果用TreeMap和Trie来查询字符串,TreeMap的时间复杂度为O(logn),而Trie的时间复杂度和总数n无关
阅读全文
摘要:对于有一类问题,我们关心的是一个线段(区间),比如区间染色、区间查询 对于一个给定的区间,更新区间中一个元素的值或者查询区间中的最大最小值或者总和,使用线段树更快,又称区间树 线段树是一种平衡二叉树(最大深度和最小深度差值<=1,堆也是平衡二叉树),其节点存储的是一个区间的信息,比如该区间的总和,根
阅读全文
摘要:复杂度总结 7大比较排序算法 时间复杂度 空间复杂度 特殊情况下的优化 应用 选择排序 O(n^2) O(1) \ \ 插入排序 O(n^2) O(1) 完全有序数组,O(n) \ 冒泡排序 O(n^2) O(1) 完全有序数组,O(n) \ 归并排序 O(nlogn) O(n) 完全有序数组,O(
阅读全文
摘要:基本思想:通过循环,让数组越来越有序 冒泡排序法在每次循环时只处理相邻的逆序对,当一个较小的元素在后面的时候,每次也只能往前挪一位,效率很低,但会让数组变得更加有序 而插入排序法在数组有序的时候,只需要和前面的一个元素比较大小,就可以终止循环 因此,希尔排序法在冒泡排序法和插入排序法的基础上,不仅仅
阅读全文
摘要:基本思想:每次只比较相邻的两个元素,如果前者比后者大就互换,每一轮会找出最大的元素,放在最后的位置,而最后的位置每轮会往前挪一位 循环不变量:第i轮时,arr[n- i, n)已排好序,在arr[n - i - 1]放上正确的元素 实现冒泡排序法 import java.util.Arrays; p
阅读全文
摘要:什么是优先队列 普通队列:先进先出,后进后出 优先队列:出队顺序和入队顺序无关,和优先级相关 实现优先队列的数据结构 入队 出队(拿出最大元素) 普通线性结构 O(1) O(n) 顺序线性结构 O(n) O(1) 堆 O(logn) O(logn) interface Queue<E> { int
阅读全文
摘要:在普通堆排序中,原始的数组必须要先添加进一个maxHeap堆,再将堆中的元素取出来放到一个temp数组,这个堆和数组都需要消耗额外的空间,是非原地排序,复杂度都是O(nlogn) 因此可以对这两个过程进行优化: 不用将原始数组添加进一个额外的堆,而是直接将原始数组看成一个堆,用heapify()方法
阅读全文
摘要:动态数组实现二叉堆 二叉堆的定义 二叉堆是一颗完全二叉树,元素按层级从左到右排列成树。空的分支只能在右下方 堆中每个节点的值都大于等于其孩子的值(最大堆) 根节点索引从1开始,从上到下、从左到右依次用数组存储,父节点索引为n时,子节点为2n和2n + 1;子节点为n时,父节点为1/2n 根节点索引从
阅读全文
摘要:基于二分搜索树的集合实现(Set) 不能添加重复元素 集合是有序的,效率高 interface Set<E>{ void add(E e); void remove(E e); boolean contains(E e); int getSize(); boolean isEmpty(); } cl
阅读全文
摘要:常用树结构 二分搜索树 平衡二分搜索树(AVL)、红黑树 堆;并查集 线段树;Trie(字典树、前缀树) 二叉树基础 和链表一样,二叉树是一种动态数据结构,数据存储在“节点”(Node)中,left指针指向左孩子,right指针指向右孩子 二叉树具有唯一根节点,每个节点最多有两个孩子,没有孩子的节点
阅读全文
摘要:upper 查找大于target的第一个元素 public class Algorithm { public static void main(String[] args) { Integer[] arr = {1, 1, 3, 3, 5, 5}; for (int i = 0; i <= 6; i
阅读全文
摘要:对于有序数组,才能使用二分查找法,需要先排序,常应用于需要多次查找的情况 选定一个标定点,将数组分为左右两个区间,时间复杂度为O(logn) 递归写法 public class Algorithm { public static void main(String[] args) { Integer[
阅读全文
摘要:核心思想:将数组拆分成三个区间,对于等于标定点的元素,也单独划分区间来保存,在下次循环的时候不考虑这部分区间,如果是元素相同的数组,就不会重复遍历这些元素了,这称为三路快速排序法 设置三个指针lt、gt和i,lt指向左区间最后一个元素,gt指向右区间第一个元素,当arr[i] < arr[left]
阅读全文
摘要:为了解决数组中重复元素过多导致的性能退化,重新思考partition()方法的逻辑,在原有的基础上,从两端分别进行比较大小,就算是完全有序的数组,也可以让p处于中间位置而不是left 核心思想:将数组划分为 >= arr[left]和 ⇐ arr[left]两个区间,设置两个遍历指针i和j,i指向左
阅读全文
摘要:随机化选择标定点 为了解决对有序数组排序,快速排序法复杂度变成O(n^2)的问题,在partition()方法中随机化选择一个元素作为标定点 import java.util.Arrays; import java.util.Random; public class Algorithm { publ
阅读全文
摘要:核心思想:快速排序法也是一种分治算法 先定义一个partition()方法找到第一个元素的正确位置,返回其真正的索引p,称为标定点 即p前面的元素都比它小,p后面的元素都比它大,由此将数组分为两个子区间 然后再递归调用快速排序对两个分区间进行同样的操作,最终完成排序 实现快速排序法 import j
阅读全文

浙公网安备 33010602011771号