二分求幂(pow的logn算法)

本文介绍了二分求幂算法的两种实现方式:递归与非递归。递归方式来源于《剑指offer》,通过不断将指数折半来减少计算次数;非递归方式来自王道计算机考研指南,同样采用指数折半的策略,但使用循环而非递归来实现。

二分求幂,最初是在剑指offer上看到,书中给出了递归的代码,后来在王道机试指南上再次看到,那上面给出了非递归的代码。

二分求幂的原理如图:


剑指offer上的递归代码如下:

double powerWithUnsignedExponent(double base,unsigned int exponent)
{
	if(exponent==0)
		return 1;
	if(exponent==1)
		return base;
	double result=powerWithUnsignedExponent(base,exponent>>1);//exponent>>1即exponent/2 
	result*=result;
	if(exponent & 0x1==1)//a & 0x1相当于a%2 
		result*=base;
	return result;
}

王道书上的非递归代码如下:

int power(int a,int b)
{
	int ans=1;
	while(b!=0)
	{
		if(b%2==1)
			ans*=a;
		b/=2;
		a*=a;
	}
	return ans;
}


### C语言实现O(logn)时间复杂度的算法示例 以下是一些C语言中时间复杂度为O(logn)算法示例,这些算法通过减少问题规模或使用指数增长逻辑来实现对数级别的复杂度。 --- #### 示例1:二分查找算法 二分查找是一种经典的O(logn)算法,适用于已排序数组。它通过不断将搜索范围缩小一半来定位目标值。 ```c int binary_search(int arr[], int size, int target) { int left = 0; int right = size - 1; while (left <= right) { int mid = left + (right - left) / 2; // 防止溢出 if (arr[mid] == target) { return mid; // 找到目标值,返回索引 } else if (arr[mid] < target) { left = mid + 1; // 在右半部分继续查找 } else { right = mid - 1; // 在左半部分继续查找 } } return -1; // 未找到目标值 } ``` 上述代码实现了二分查找算法。假设数组`arr`是有序的,算法通过不断将搜索范围缩小一半来定位目标值`target`。每次迭代都将问题规模减半,因此其时间复杂度为O(logn)[^1]。 --- #### 示例2:计算最接近的2的次 该算法通过不断将变量加倍来逼近目标值`n`,直到变量大于或等于`n`为止。这种指数增长逻辑的时间复杂度为O(logn)。 ```c int find_logn(int n) { int cnt = 1; int steps = 0; while (cnt < n) { cnt *= 2; // 每次将cnt加倍 steps++; // 记录加倍次数 } return steps; // 返回加倍次数,表示logn的结果 } ``` 在该代码中,变量`cnt`每次迭代都会乘以2,直到它大于或等于`n`为止。由于`cnt`的增长是指数级的,循环的执行次数与`log_2n`成正比,因此时间复杂度为O(logn)[^3]。 --- #### 示例3:快速算法Pow(x, n)) 快速算法用于高效计算运算`x^n`,其时间复杂度为O(logn)。通过将指数`n`分解为二进制形式,可以减少乘法操作的次数。 ```c double pow(double x, int n) { double result = 1.0; long long abs_n = (n >= 0) ? n : -(long long)n; while (abs_n > 0) { if (abs_n & 1) { // 如果当前位是1 result *= x; } x *= x; // 将底数平方 abs_n >>= 1; // 将指数右移一位 } return (n >= 0) ? result : 1 / result; } ``` 在上述代码中,通过将指数`n`分解为二进制形式,并利用位运算判断每一位是否为1,减少了乘法操作的次数。每次迭代都将指数`n`除以2(等价于右移一位),因此时间复杂度为O(logn)[^2]。 --- #### 示例4:寻找第一个大于等于目标值的元素 此算法类似于二分查找,但目标是找到第一个大于等于目标值的元素。它的时间复杂度同样为O(logn)。 ```c int first_ge(int arr[], int size, int target) { int left = 0; int right = size; while (left < right) { int mid = left + (right - left) / 2; if (arr[mid] < target) { left = mid + 1; // 目标值在右侧 } else { right = mid; // 目标值可能在左侧或当前位置 } } return (left < size && arr[left] >= target) ? left : -1; } ``` 该算法通过不断缩小搜索范围来找到第一个大于等于目标值的元素。每次迭代都将问题规模减半,因此时间复杂度为O(logn)[^1]。 --- ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值