05 2022 档案
摘要:14.6:排序总结 1、不基于比较的排序,对样本数据有严格的要求,不易改写。 2、基于比较的排序,只要规定好两个样本怎么比大小就可以直接复用。 3、基于比较的排序,时间复杂度的极限是O(N * logN)。 4、时间复杂度O(N * logN)、额外空间复杂度低于O(N)、且稳定的基于比较的排序是不
阅读全文
摘要:14.5:真正意义上的快排:随机快排 [ ....?... X] 随机从数组中选一个数和最右侧的数进行交换, [ ....X... ?] 拿这个?数作为目标数 将数组划分成: [ <? ==? >? ?] 只需要将最后?和>?区域的第一数交换,?就来到了==?区域 [ <? ==? ? >? ] 此
阅读全文
摘要:14.4:快排2.0 [ ..... X] 利用数组的最后一个数X作为目标数 将数组划分成: [ <X ==X >X X] 只需要将最后X和>X区域的第一数交换,X就来到了==X区域 [ <X ==X X >X ] 此时==X的位置固定下来,不用变了。 通过递归: 处理[ <x ]区域 处理[ >x
阅读全文
摘要:14.3:快排1.0 [ ..... X] 利用数组的最后一个数X作为目标数 将数组划分成: [ <=X >X X] 只需要将最后X和>X区域的第一数交换,X就来到了==X区域 [ <=X X >X ] 此时X的位置固定下来。 通过递归: 处理[ <=x ]区域 处理[ >x ]区域
阅读全文
摘要:14.2:荷兰国旗问题:分3区域 分3区域、<X 放左边,X放中间, >X放右边 例子: <)[ 3, 4, 6, 0, 7, 4, 5, 1, 3 ](> 目标数:4 1、当前数 < 目标数,当前数和小于区的下一个数交换,小于区右括,当前数跳下一个。 2、当前数 == 目标数,当前数直接跳下一个。
阅读全文
摘要:14.1:荷兰国旗问题:分2区域 有数组arr[ L ...R ],给你一个数X, 拿X去划分数组 1:分2区域、<=X 放左边, >X放右边 2:分3区域、<X 放左边,X放中间, >X放右边 再划分后的区域内,不要求一定有序。 要求不用辅助数组,时间复杂度O(N) 1、当前数<=目标,当前数和(
阅读全文
摘要:14:快排 前置知识:荷兰国旗问题 比较: 快排1.0 快排2.0 和随机快排
阅读全文
摘要:https://leetcode-cn.com/problems/count-of-range-sum/ 套例子: 0 1 2 3 arr[ 1, -1, -2, 3] 范围[ -1, 1 ] 暴力解法: 0-0 [ 1 ] 累加和1 符合范围 √ 0-1[1,-1] 累加和0 符合范围 √ 0-2
阅读全文
摘要:前置知识:前缀累加和 arr[ i ....j ] 求sum[ i, j ]的和 等价于 sum[ i, j ] = preSum[ 0, j ] - preSum[ 0, i-1 ] 前缀和的生成: index 0 1 2 3 4 5 6 arr [-3, 1, 2, 4, 0, -1, 5] 遍
阅读全文
摘要:13.6 : 加强堆,通过改写经典堆的底层代码
阅读全文
摘要:13.5: 最大线段重合问题(堆实现),敏感度 给定很多线段,每个线段都有左右两个位置 [ start, end ],表示线段开始位置和结束位置,左右都是闭区间, 规定: 1、线段的开始和结束位置一定都是整数值; 2、线段重合区域的长度必须 >= 1,一个点不算重合区域; 线段 a [1, 3] b
阅读全文
摘要:13.4:建堆两种方式以及时间复杂度讨论 这也是堆这一章节最重要的两方法,涉及到后面的加强堆的实现。 1、如果是一个数一个数的给,自然可以通过heapInsert()来建堆,这是自下而上的方式, 时间复杂度O(N * logN); 2、给一个数组建堆也可以通过heapify()的方式,这是自上而下的
阅读全文
摘要:13.3:堆排序说明 基于比较的排序时间复杂度O(N * logN)是最好的了 1、先让整个数组都变成大根堆,建立堆的过程 1.1、从上到下的方法,时间复杂度O(N * logN) 1.2、从下到上的方法,时间复杂度O(N) 2、把堆的最大值和堆末尾的值交换,然后减少堆的大小之后,再去调整堆,一直周
阅读全文
摘要:13.2:堆排序 基于比较的排序时间复杂度O(N * logN)是最好的了 理解了堆以及堆里面的heapInsert() 和heapify(),堆排序就简单了。 1、把数组中的所有数都调成大根堆。heapSize = N。 2、0位置的数和N-1位置的数进行交换。heapSize = N - 1。
阅读全文
摘要:13.1:堆的heapify下沉过程 现在的要求是: 此时在大根堆上,将最大的数max返回,剩下的数自动按照大根堆的要求重新建成新的大根堆? 操作思路: [ 8 7 0 1 6 ] 下标: 0 1 2 3 4 我们知道大根堆上最大值一定在index = 0位置上,所以给用户直接返回max = 8没问
阅读全文
摘要:13:堆结构heap (priority queue)重要结构 之 上移过程heapInsert() 1、堆结构就是用数组实现的完全二叉树结构; 2、完全二叉树中如果每棵树(包括子数) 的最大值都在顶部 是 大根堆; 3、完全二叉树中如果每棵树(包括子数) 的最小值都在顶部 是 小根堆; 4、堆结构
阅读全文
摘要:12:比较器 1、比较器的实质是重载比较运算符; 2、比较器可以很好的应用在特殊标准的排序上; 3、比较器可以很好的应用在根据特殊标准的结构上; 4、写代码异常容易,还用于泛型编程; 1 public static class Student { 2 public String name; 3 pu
阅读全文
摘要:11.3:逆序对问题 [3 1 0 4 3 1] 在这个数组里有多少个逆序对? 从某个数开始往后看 1、3 1;3 0;3 1; 2、1 0; 3、4 3; 4 1; 4、3 1; 现在是不是在说每个数的右边有多少个数比它小? 经典方法从右往左merge,规则 1、当两个数相等的时候,先拷贝右组数。
阅读全文
摘要:11.4:大于2倍问题 [ 6 7 1 3 2] 每个数num,问num右边 有多少个数满足 :num > 右*2 6; 1 和 2; 6 > 右侧有2个数 [ 1 2 ] 乘以2 7; 1、3和2; 7 > 右侧有3个数 [1 2 3 ] 乘以2 1; 1 > 右侧有0个数 [ ] 乘以2 3;
阅读全文
摘要:11.2:小和问题,暴力求解和归并思想求解 例: [ 6 3 2 1 6 7] 每个数左边,比它小的数累加起来 6; 6的左边有多少个数比6小,0个; 3; 3的左边有多少个数比3小,0个; 2; 2的左边有多少个数比2小,0个; 1; 1的左边有多少个数比1小,0个; 6; 6的左边有多少个数比6
阅读全文
摘要:11.1:归并非递归实现 步长变化: 1 2 4 8 16 32 ... 一旦超过N步长停 logN次 1 // 非递归方法实现 2 public static void mergeSort(int[] arr) { 3 if (arr == null || arr.length < 2) { 4
阅读全文
摘要:11:归并排序(重要) 时间复杂度:O(N * logN) 与O(N^2)排序算法的比较: 1、O(N^2)大量浪费了比较行为。 2、归并排序,当左组和右组的排序排好后,在merge的时候, 左组数之间是没有比较的。 是左组数与右组数的比较。 每一次比较行为都变成了结果并且再传递下去。 算法流程:
阅读全文
摘要:10:Java中的哈希表和有序表 哈希表在使用时,增删改查时间复杂度都是O(1); 有序表在使用时,比哈希表功能多,时间复杂度都是O(logN); 哈希表: 1、哈希表在使用层面上可以理解为一种集合结构; 2、如果只有key,没有伴随数据value,可以使用HashSet结构; 3、如果既有key,
阅读全文
摘要:9.1:Master公式 T(N) = a * T(N/b) + O(N^d); 其中a、b、d都是常数的递归函数,可以直接通过Master公式来确定时间复杂度。 如果log(b, a)< d, 复杂度O(N^d) 如果log(b, a)> d, 复杂度O(N^log(b, a)) 如果log(b,
阅读全文
摘要:9:递归 递归的应用十分重要,后面会反复出现。 求数组arr[L ... R]中最大值,怎么用递归方法实现 1 // 求arr中的最大值 2 public static int getMax(int[] arr) { 3 return process(arr, 0, arr.length - 1);
阅读全文
摘要:8.7:如何用队列结构实现栈结构 1 public static class TwoQueueStack<T> { 2 3 public Queue<T> queue; 4 public Queue<T> help; 5 6 public TwoQueueStack() { 7 queue = ne
阅读全文
摘要:8.6:如何用栈结构实现队列结构 两栈:push栈 和 pop栈 倒数据的要求: 1、如果倒数据,必须一次性倒完。 2、如果pop栈不为空,不能倒数据。pop栈空了才能倒数据。 1 public static class TwoStacksQueue { 2 public Stack<Integer
阅读全文
摘要:8.5:实现特殊栈,在基本功能的基础上,再实现返回栈中最小元素的功能 1、pop,push,getMin操作的时间复杂度是o(1)。 2、设计的栈类型可以使用现成的栈结构。 两个栈,一个数据栈,一个最小栈。每次数据过来压入数据组,同时压入最小栈,但压入最小 栈是有条件的: 1、如果最小栈中没有数,压
阅读全文
摘要:8.3:数组实现队列(难) 用size解耦 pushi和polli 1 //数组实现队列,先进先出 2 //通过size解耦end和begin 3 public static class MyQueue { 4 private int[] arr; 5 private int end; // pus
阅读全文
摘要:8.2:双向链表实现栈 底层都是双链表调整 1 public static class Node<T> { 2 public T value; 3 public Node<T> last; 4 public Node<T> next; 5 6 public Node(T data) { 7 valu
阅读全文
摘要:8.1:双向链表实现双端队列 双端队列,玩的head 和tail指针 底层都是双链表调整 1、双向链表 节点1 public static class Node<T> { 2 public T value; 3 public Node<T> last; 4 public Node<T> next;
阅读全文
摘要:8:栈和队列 逻辑概念: 栈:数据先进后出,犹如弹匣 队列:数据先进先出,好似排队 栈和队列的实现: 1、双向链表实现 2、数组实现
阅读全文
摘要:7.2:链表删除给定值 1 // head = removeValue(head, 2); 2 public static Node removeValue(Node head, int num) { 3 // head来到第一个不需要删的位置 4 while (head != null) { 5
阅读全文
摘要:7.1:链表反转 链表反转注意:返回头部节点。 单链表的反转 // head // a -> b -> c -> null // c -> b -> a -> null public static Node reverseLinkedList(Node head) { Node pre = null
阅读全文
摘要:7:链表结构 单向链表节点结构 public static class Node { public T value; public Node next; public Node(T data) { value = data; } } 双向链表 public static class Node<T>
阅读全文
摘要:6.4: 一个数组中有一种数出现K次,其它数都出现了M次,M > 1, K < M,找到出现K次的数,要求,额外空间复杂度O(1),时间复杂度O(N) 例如:arr[] 其中2出现K次,9出现M次,M != 1,M > 1, K < M。 1 // 请保证arr中,只有一种数出现了K次,其它数都出现
阅读全文
摘要:6.3:一个数组中有两种数出现了奇数次,其它数出现了偶数次,怎么找到并打印这两种数 两种数出现奇数次,其它偶数次 1、用eor = 0去逐个异或,最后一定是 eor = a^b, a和b是这个两个出现奇数次的数。偶数次异或为0。 2、a != b, eor != 0; eor的binary一定有1,
阅读全文
摘要:6.2:怎么把一个int类型的数,提取出最右侧的1来 int a = 01101110010000 ?处理后 int ans =00000000010000,返回。 a&((~a)+1) == a&(-a) int a = 01101110010000 ; ~a = 10010001101111 &
阅读全文
摘要:6.1:一个数组中有一种数出现了奇数次,其它数出现了偶数次,怎么找到并打印这种数? 方法一:哈希表统计词频,找到奇数次的那个数 方法二:异或运算 [4,3,4,2,4,3,1,2,1,1,1,3,3],其中1111,22,3333,444 eor = 0 去异或1111,22,3333,444 得到
阅读全文
摘要:6:异或运算 异或运算:相同为0,不同为1 同或运算:相同为1,不同为0 So,异或运算记成无进位相加 int a = 7; Binary 00111 int b= 13; 01101 a^b = ? 01010 = 10 性质: 1) 0^N = N 2) N^N= 0 3)满足交换律和结合律 a
阅读全文
摘要:5:二分法 常见的二分是在有序数组上的开展的二分搜索。 有时,有序非必要条件,会给定特定条件,只要能正确构建左右两侧的淘汰逻辑,就可以二分。 二分最经典的例子:取一半时,向下取整 在有序数组中,找某个数是否存在。 比较 mid = (L+R)/2 不安全,会溢出 mid = L + ((R - L)
阅读全文
摘要:4:对数器 没有OJ怎么办? 问题,总有办法解决,有差办法比如纯暴力的尝试,有最优解。总可以搞出2种以上的解决思路。 产生随机数据在2套思路中跑出来的数据进行对比,如果几百万次,几千万次,跑出来的结果都是一样的,小概率事件:我们写的最优解出错。 1 public static void main(S
阅读全文
摘要:3:插入排序 插入排序思想描述: 1、数组0到0位置,只有1个数,必定有序 2、数组0~1位置,盯着1位置的数,往左看:如果arr[1]>arr[0]停止。否则arr[0]与arr[1]交换, 再看arr[0]的左边有没有数,没数了停止。此时0~1位置上数有序。 3、数组0~2位置,盯着2位置的数,
阅读全文
摘要:2:冒泡排序 冒泡排序思想描述: 1、第一轮:从小到大两两比较0~1 1~2 2~3 3~4 4~5 5~6 .... N-2~N-1,谁大谁往后。第一轮把最大的那个数,排到N-1位置上。 2、第二轮:两两比较0~1 1~2 2~3 3~4 4~5 5~6 .... N-3~N-2,谁大谁往后。第二
阅读全文
摘要:选择排序算法思想描述: 1、定义变量minIndex每次都指向全局最小值 2、从数组0位置开始,minIndex = 0,把1~N-1位置上的每一个数依次取出(用下标j指向)和minIndex位置的数比较, 如果取出的这个数arr[j]比arr[minIndex]的数小,更新minIndex = j
阅读全文