[TOC]
冒泡排序
1 | public class bubbleSort { |
快速排序
1 | public class QuickSort { |
时间复杂度推导
我们用T(n)来表示时间复杂度,有:
解这个递推公式:
有)代入上一个公式有
有)代入上一个公式有
…
最后一层递归有)代入上一个公式有
已知最后一层递归时操作次数为1,),有
带入公式)得
有T(1)=0;
所以 即:O(nlgn);
看着好复杂,我的简单理解是,每一轮复杂度都是n,每一轮劈两半,能劈2^x=n x=logn轮,总复杂度就是nlogn
最好情况,每层左右子树都可以平均分摊,层高是n对2取log,否则倒叙输入,每层左子树只能分担一个,退化为层高n的树
插入排序
1 | public class InsertSort { |
归并排序
1 | public class test { |
堆排序
建堆的时间复杂度
1 | 首先要理解怎么计算这个堆化过程所消耗的时间,可以直接画图去理解; |
1 | 更改堆元素后重建堆时间:O(nlogn) |
1 | public class HeapSort { |
时间复杂度:
选择排序
1 | public class SelectSort { |
希尔排序
1 | public class shellSort { |
洗牌算法
笔试时,遇到一个算法题:差不多是 在n个不同的数中随机取出不重复的m个数。洗牌算法是将原来的数组进行打散,使原数组的某个数在打散后的数组中的每个位置上等概率的出现,刚好可以解决该问题。
该算法是经典洗牌算法。它的proof如下:
对于arr[i],洗牌后在第n-1个位置的概率是1/n(第一次交换的随机数为i)
在n-2个位置概率是[(n-1)/n] * [1/(n-1)] = 1/n,(第一次交换的随机数不为i,第二次为arr[i]所在的位置(注意,若i=n-1,第一交换arr[n-1]会被换到一个随机的位置))
在第n-k个位置的概率是[(n-1)/n] * [(n-2)/(n-1)] … [(n-k+1)/(n-k+2)] *[1/(n-k+1)] = 1/n
1 | 该算法的基本思想和 Fisher 类似,每次从未处理的数据中随机取出一个数字,然后把该数字放在数组的尾部,即数组尾部存放的是已经处理过的数字。 |
1 | public class hello { |
最短路径
1 | [[1,1,0,1], |
1 | static int min=Integer.MAX_VALUE; |
不同的数字
一个有序数组,有重复的数,平方后,数组当中有多少不同的数字,例子,[-1,3,3],返回结果 2.
例子,[-1,-1,1,1],返回结果 1. nums = {-2,-1,0,1,2,3} 返回4
1 | public int findDiff(int[] nums) { |
leetcode hard
股票问题
4 中位数
10 正则匹配
23 合并K个
41 缺失第一个正数
44 通配符匹配
124 二叉树最大路径和
146 LRU