22.1.7 master公式及O(NLogN)的排序
22.1.7 master公式及O(NLogN)的排序
1 master 公式
(1) 写公式
T(N) = a * T(N/b) + O(N^d);
master公式用来求递归行为的时间复杂度,式中T(N/b)表示母问题被分解为子问题的规模,a表示子问题被调用的次数,O(N^d)表示算法中其他过程的时间复杂度。
例如:
public static int getMax(int[] arr)
{
return process(arr,0,arr.length-1);
}
public static int process(int[] arr,int L,int R)
{
if(L==R)
return arr[L];
int mid = L+((R-L)>>1);//mid = L+((R-L)/2),/2可以表示为右移一位。
int leftMax = process(arr,L,mid);
int rightMax = process(arr,mid,R);
return Math.max(leftMax,rightMax);
}其中,T(N) = 2 * T(N/2) + O(1);a = 2,b = 2,d = 0;
(2)求时间复杂度:
log以b为底a的对数 < d , 时间复杂度为O(N^d);
log以b为底a的对数 > d , 时间复杂度为O(N^log以b为底a的对数);
log以b为底a的对数 = d , 时间复杂度为O((N^d) * logN);
2 O(NLogN)的排序:
(1) 归并排序:
public static void main(String[] args)
{
int[] arr = {2,4,6,4,6,7,1,8,3,9,8};
process(arr,0,arr.length-1);
for(int cur:arr)
{
System.out.print(cur+" ");
}
}
public static void process(int[] arr,int L,int R)
{
if(L==R)
return;
int mid = L+((R-L)>>1);
process(arr,L,mid);
process(arr,mid+1,R);
mergeSoft(arr,L,mid,R);
}
public static void mergeSoft(int[] arr,int L,int M,int R)
{
int[] help = new int[R-L+1];
int i=0;
int p1 = L;
int p2 = M+1;
while(p1<=M && p2<=R)
{
help[i++] = arr[p1]<=arr[p2]?arr[p1++]:arr[p2++];
}
while(p1<=M)
help[i++] = arr[p1++];
while(p2<=R)
help[i++] = arr[p2++];
for(i=0;i<help.length;i++)
arr[L+i] = help[i];
}
example:小和问题,求逆序对
小和问题描述:对于一个数组例如,2,1,5,8,9,6,3,4。其中2和5,8,9,6,3,4都会产生小和2,同理1与5,8,9,6,3,4也都会产生小和1,依次累加所有的小和然后返回。
//小和问题
public static void main(String[] args)
{
int[] arr = { 2,1,5,8,9,6,3,4};
int res = smallSum(arr);
System.out.println(res+" ");
}
public static int smallSum(int[] arr)
{
if(arr == null || arr.length<2)
return -1;
return process(arr,0,arr.length-1);
}
public static int process(int[] arr,int L,int R)
{
if(L==R)
return 0;
int mid = L+((R-L)>>1);
return process(arr,L,mid)+process(arr,mid+1,R)+mergeSoft(arr,L,mid,R);
}
public static int mergeSoft(int[] arr,int L,int M,int R)
{
int[] help = new int[R-L+1];
int i=0;
int p1 = L;
int p2 = M+1;
int res = 0;
while(p1<=M && p2<=R)
{
res +=arr[p1]<arr[p2]?((R-p2+1)*arr[p1]):0;
help[i++] = arr[p1]<=arr[p2]?arr[p1++]:arr[p2++];
}
while(p1<=M)
help[i++] = arr[p1++];
while(p2<=R)
help[i++] = arr[p2++];
for(i=0;i<help.length;i++)
arr[L+i] = help[i];
return res;
}
(2) 快速排序
public static void main(String[] args)
{
int[] arr = { 2,1,5,8,9,6,3,4};
quickSort(arr,0,(arr.length-1));
}
public static void swap(int[] arr ,int l,int r)
{
int temp = arr[r];
arr[r] = arr[l];
arr[l] = temp;
}
public static void quickSort(int[] arr,int l,int r)
{
if(l<r)
{
swap(arr,l+(int)(Math.random()*(r-l+1)),r);
int[] p =partition(arr,l,r);
quickSort(arr,l,p[0]-1);
quickSort(arr,p[1]+1,r);
}
}
public static int[] partition(int[] arr,int l,int r)
{
int less = l-1;
int more = r;
while(l<more)
{
if(arr[l]<arr[r])
{
swap(arr,++less,l++);
}
else if(arr[l]>arr[r])
{
swap(arr,--more,l);
}
else
l++;
}
swap(arr,more,r);
return new int[]{less+1,more};
}
22.1.7 master公式及O(NLogN)的排序的更多相关文章
- Master公式计算递归时间复杂度
我们在算递归算法的时间复杂度时,Master定理为我们提供了很强大的便利! Master公式在我们的面试编程算法中除了BFPRT算法的复杂度计算不了之外,其他都可以准确计算! 这里用求数组最大值的递归 ...
- 算法初级面试题01——认识时间复杂度、对数器、 master公式计算时间复杂度、小和问题和逆序对问题
虽然以前学过,再次回顾还是有别样的收获~ 认识时间复杂度 常数时间的操作:一个操作如果和数据量没有关系,每次都是固定时间内完成的操作,叫做常数操作. 时间复杂度为一个算法流程中,常数操作数量的指标.常 ...
- 数据结构与算法学习(二)——Master公式及其应用
本篇文章涉及公式,由于博客园没有很好的支持,建议移步我的CSDN博客和简书进行阅读. 1. Master公式是什么? 我们在解决算法问题时,经常会用到递归.递归在较难理解的同时,其算法的复杂度也不是很 ...
- 左神算法第一节课:复杂度、排序(冒泡、选择、插入、归并)、小和问题和逆序对问题、对数器和递归(Master公式)
第一节课 复杂度 排序(冒泡.选择.插入.归并) 小和问题和逆序对问题 对数器 递归 1. 复杂度 认识时间复杂度常数时间的操作:一个操作如果和数据量没有关系,每次都是固定时间内完成的操作,叫做常数 ...
- 转:master公式(主方法)
master公式(也称主方法)是利用分治策略来解决问题经常使用的时间复杂度的分析方法,(补充:分治策略的递归解法还有两个常用的方法叫做代入法和递归树法),众所众知,分治策略中使用递归来求解问题分为三步 ...
- 备战秋招之十大排序——O(nlogn)级排序算法
时间复杂度O(nlogn)级排序算法 五.希尔排序 首批将时间复杂度降到 O(n^2) 以下的算法之一.虽然原始的希尔排序最坏时间复杂度仍然是O(n^2),但经过优化的希尔排序可以达到 O(n^{1. ...
- 数据结构与算法——认识O(NlogN)的排序(1)
归并排序 1) 整体就是一个简单递归,左边排好序.右边排好序.让其整体有序 2) 让其整体有序的过程里用了外排序方法 3) 利用master公式来求解时间复杂度 4) 归并排序的实质 时间复杂度0(N ...
- 时间复杂度为O(nlogn)的排序算法
时间复杂度为O(nlogn)的排序算法(归并排序.快速排序),比时间复杂度O(n²)的排序算法更适合大规模数据排序. 归并排序 归并排序的核心思想 采用"分治思想",将要排序的数组 ...
- master公式 ------ 求递归情况下的时间复杂度
剖析递归行为和递归行为时间复杂度的估算一个递归行为的例子T(N) = a*T(N/b) + O(N^d)1) log(b,a) > d -> 复杂度为O(N^log(b,a))2) log ...
随机推荐
- 通过shell脚本进行linux服务器的CPU和内存压测
文章目录 内存压测 python的方式 shell的方式 cpu压测 在正常手段下,这个只是压测的方法 在不正常手段下(crontab计划任务),可以提高CPU和内存的使用率 什么?你问我为什么要提高 ...
- python的format
python的format 就是一个参数传递+格式化的过程 参数传递 1.位置传递,默认 fmt = "{} {}" fmt.format("hello",&q ...
- 阿里云人脸1:N搜索开源版-Java版(文末附开源地址)
一.人脸检测相关概念 人脸检测(Face Detection)是检测出图像中人脸所在位置的一项技术,是人脸智能分析应用的核心组成部分,也是最基础的部分.人脸检测方法现在多种多样,常用的技术或工具大 ...
- Java IO 技术
文章目录 流的概念 IO 流类体系 InputStream / OutputStream Reader / Writer 文件字节流 文件字符流 缓冲字节流 缓冲字符流 字节数组流 数据流 转换流 序 ...
- (一)scrapy 安装及新建爬虫项目并运行
> 参考:https://www.cnblogs.com/hy123456/p/9847570.html 在 pycharm 中并没有创建 scrapy 工程的选项,需要手动创建. 这里就有两种 ...
- [题解]RQNOJ PID87 过河
链接:http://www.rqnoj.cn/problem/87 思路:动态规划 定义f[i][j]表示到达第 i 块给定石头用了 j 块添加石头的最少步数. 转移方程:f[i][j]=min{f[ ...
- 反编译C#代码来看看闭包到底是什么
原文地址:https://zhuanlan.zhihu.com/p/3161634 C#的闭包,是一个语法糖. 它实质上是将匿名函数转换成一个类,函数作为其中的类方法,并调整外部调用代码来实现的.既然 ...
- Kubernetes集群搭建(详细)
kubernetes集群搭建(kubeadm方式) kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具.这个工具能通过两条指令完成一个kubernetes集群的部署: # 创 ...
- Scala学习笔记(详细)
第2章 变量 val,var,声明变量必须初始化:变量类型确定后不可更改 数据类型:与java有相同的数据类型,在scala中数据类型都是对象 特殊类型:Unit:表示无值,只有一个实例值写出(),相 ...
- 编译安装nginx报错 checking for C compiler ... not found
编译安装在执行./configure步骤报错,是因为缺少环境变量 checking for C compiler - not found ./configure: error: C compiler ...