递归算法求数组最大值与master公式计算时间复杂度

问题:给定一个长度为N的数组arr[0,N-1],使用递归算法求最大值,并计算时间复杂度
编码:

public static int process(int arr[],int l,int R){//arr代表数组,L代表最小下标,R代表最大下标
	if(L==R){
		return arr[L];//如果数组内只有一个元素,那最大值就是这个数
	}
	int mid=L+((R-L)>>1);
	int leftMax=process(arr,L,mid);
	int rightMax=process(arr,mid+1,R);
	return Math.max(leftMax,rightMax);
}

代码解释:

int mid=L+((R-L)>>1);
//取数组范围的中间数
//如果使用传统的(L+R)/2,当数组内的元素非常大,接近int的最大值,此时如果我想取数组中间范围的最大值
//那么就很可能会造成溢出,溢出之后再除2就会报错,所以选择先用R-L,然后除2,再加上L,得出的就是中间数
//比如范围是[10000,20000],那么计算过程就是20000-10000然后除2得到5000,加上L得到15000即为中间数
//至于除2为什么使用右移一位,因为右移一位相当于除2,但是比直接除2效率要高,对应的,左移一位就相当于乘2
int leftMax=process(arr,L,mid);
//取到中间数之后,再将L到中间数作为一个范围,重复调用process,直到返回一个最大值
int rightMax=process(arr,mid+1,R);
//取到中间数之后,再将中间数到R作为一个范围,重复调用process,直到返回一个最大值

上面两句代码,转换为流程图理解如下
在这里插入图片描述

Master公式

T(N)=a*T(N/b)+O(N^d)
理解:其中 a >= 1 and b > 1 是常量,其表示的意义是n表示问题的规模,a表示递归的次数也就是生成的子问题数,b表示每次递归是原来的1/b之一个规模,f(n)表示分解和合并所要花费的时间之和。
条件:想要使用这个公式,必须满足一个条件,所有的子方法的规模必须相同
计算方法:

①当d<logb^a时,时间复杂度为O(n^(logb^a))
②当d=logb^a时,时间复杂度为O((n^d)*logn)
③当d>logb^a时,时间复杂度为O(n^d)

以上面的递归方法为例:子方法为process,int leftMax=process(arr,L,mid);调用了一次process,规模为N/2,因为将数组平均分为两半,int rightMax=process(arr,mid+1,R);调用了一次process,规模也是N/2,剩下的只是Math.max(leftMax,rightMax);作了一次比较,没有进行循环,所以时间复杂度为O(N^0)=1,这就满足了上面master的条件,a为2(两次子方法),b为1/2(规模为1/2),d为0,所以得到的master公式为T(N)=2*T(2/N)+O(1).根据计算方法,d=0,loga^b=loga/logb=log2/log2=1,所以时间复杂度为O(N)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值