-
2022-01-12 22:15:18
快速幂函数的前提条件为n>=0。递归求解能少求一次是一次。
class Solution { public: double quickMul(double x, long long n) { // n >= 0 if (n == 0) return 1.0; double y = quickMul(x, n / 2); return n % 2 ==0? y*y : y*y*x; } double myPow(double x, int n) { long long N = n; return N>=0? quickMul(x, N): 1.0/quickMul(x, -N); } };
更多相关内容 -
C语言实现分治法实例
2020-12-25 20:32:37本文为大家分享了C语言实现分治法实例代码,供大家参考,具体内容如下 使用分治法求最大值 这个函数将数组a[l]…a[r]分成a[l],…,a[m]和a[m+1],…a[r]两部分,分别求出每一部分的最大元素(递归地),并返回较大的那一个... -
分治法 实例
2018-09-27 14:27:58分治法——见名知意,即分而治之,从而得到我们想要的最终结果。分治法的思想是将一个规模为N的问题分解为k个较小的子问题,这些子问题遵循的原则就是互相独立且与原问题相同。 下面我们就用具体的例子来理解分治法...转载 特别感谢 :https://blog.csdn.net/weixin_42061805/article/detail/80291662
分治法——见名知意,即分而治之,从而得到我们想要的最终结果。分治法的思想是将一个规模为N的问题分解为k个较小的子问题,这些子问题遵循的原则就是互相独立且与原问题相同。
下面我们就用具体的例子来理解分治法的算法思想。
例题:一个装有 16 枚硬币的袋子,16 枚硬币中有一个是伪造的,并且那个伪造的硬币比真的硬币要轻。现有一台可用来比较两组硬币重量的仪器,请使用分治法设计一个算法,可以找出那枚伪造的硬币。
我们简单的分析一下这个问题,我们采用一个五五开的思想(类似于二分法)
我们先将16枚硬币分为左右两个部分,各为8个硬币,分别称重,必然得出一半儿轻一半儿重,而我们要的就是轻的那组,重的舍去。接下来我们继续对轻的进行五五分,直至每组剩下一枚或者两枚硬币,这时我们的问题自然就解决了,下面用一张图进行更好的理解。
#include<stdio.h> #include<stdlib.h> #include<time.h> #define ARRAY_SIZE 16 #define TRUE 1 #define FALSE 0 int CallTimes = 0; int TrueCoinWeight, FakeCoinWeight; // 生成包含 'N' 个硬币重量的数组( 含 1 枚伪币 ), 并返回伪币位置 ... int CreateRandomCoinWeightArray( int *p, int N ) { int i, kt; int IsStop; // 生成随机数种子 ... srand( ( unsigned )time( NULL ) ); // 生成随机真币重量值( 在 50 至 100 之间 ) ... TrueCoinWeight = 50 + rand( ) % ( 100 - 50 ); // 生成随机伪币位置( 在 0 ~ N-1 之间 ) ... kt = rand( ) % N; // 设置真币重量 ... for( i = 0; i < N; i++ ) if ( i != kt ) //kt为伪币的位置 *( p + i ) = TrueCoinWeight;//赋真币的值 // 生成 1 个比真币略轻的伪币重量值 ... IsStop = FALSE; while( !IsStop ) { FakeCoinWeight = 50 + rand( ) % ( 100 - 50 ); // 设置满足条件的伪币重量值 ... if ( ( TrueCoinWeight > FakeCoinWeight ) && ( TrueCoinWeight - FakeCoinWeight <= 5 ) ) { IsStop = TRUE; *( p + kt ) = FakeCoinWeight; } } // 返回伪币位置 ... return kt; } // 计算数组中硬币重量和 ... int CalcCoinTotalWeight( int ArrayData[], int kb, int ke ) { int i, TotalWeight = 0;//初始化重量为0 for( i = kb; i <= ke; i++ ) TotalWeight += ArrayData[ i ]; return TotalWeight; } // 采用分治法找到伪币( 假定伪币一定存在且只有 1 枚 ) ... // kb - (子)数组左边界( begin ) // ke - (子)数组右边界( end ) int FindFakeCoin( int ArrayData[], int kb, int ke ) { int LWeight, RWeight; CallTimes++; printf( "< 第 %d 次查找 > \n", CallTimes ); // 请将下面的代码补充完毕, 使程序可以正确运行 ... // ...... //左边重量和 LWeight=CalcCoinTotalWeight(ArrayData,kb,kb+(ke-kb)/2); //右边重量和 RWeight=CalcCoinTotalWeight(ArrayData,kb+(ke-kb)/2+1,ke); //取右边子数组 if((TrueCoinWeight*((ke-kb)/2+1))==LWeight) { if(RWeight==FakeCoinWeight) { printf("< Success! >\n"); //返回假币位置 return ke; } else FindFakeCoin(ArrayData,kb+(ke-kb)/2+1,ke); } //取左边子数组 else { if(LWeight==FakeCoinWeight) { printf("< Success! >\n"); //返回假币位置 return kb; } else FindFakeCoin(ArrayData,kb,kb+(ke-kb)/2); } } int main() { int ArrayData[ ARRAY_SIZE ]; int i, k, FakeCoinPos; // 生成包含 'N' 个硬币重量的数组( 含 1 枚伪币 ), 并返回伪币位置 ... k = CreateRandomCoinWeightArray( ArrayData, ARRAY_SIZE ); // 输出随机数组内容 ... printf( "< 生成的硬币重量数组值为( 含 1 枚伪币 ) > : \n" ); for( i = 0; i < ARRAY_SIZE; i++ ) printf( "第%d枚硬币重量:%d\n",i+1, ArrayData[ i ] ); printf( "\n" ); printf( "< 第 %d 枚为伪币 > \n", ( k + 1 ) ); printf( "\n" ); // 采用分治法找到伪币位置 ... FakeCoinPos = FindFakeCoin( ArrayData, 0, ARRAY_SIZE - 1 ); printf( "< 找到第 %d 枚为伪币 > \n", ( FakeCoinPos + 1 ) ); printf( "\n" ); // 等待用户输入任意一键返回 ... system( "PAUSE" ); }
-
1.1. 分治法实例—芯片测试
2022-01-12 19:09:56分治算法 算法思想:假设n为偶数,将n片芯片两两一组做测试淘汰,剩下芯片构成子问题,进入下一轮分组淘汰 淘汰规则 “好,好”——任留1片,进入下轮 其他情况——全部抛弃 递归出口:n ≤ \le ≤ 3 若为3片芯片...1. 问题描述
- 输入:n片芯片,其中好芯片至少比坏芯片多1片
- 问题:设计一种测试方法,通过测试从n片芯片中挑出1片好芯片
- 要求:使用最少的测试次数
2. 解题思路
1. 判定芯片A的好坏
- 问题:给定芯片A,判定A的好坏
- 方法:用其余n-1片芯片对A测试
2. 蛮力算法
- 算法思想:任取1片测试,如果是好芯片,则测试结束;如果是坏芯片,则抛弃,再从剩下芯片中任取1片测试,直到得到1片好芯片
- 时间估计:O(
n
2
n^2
n2)
- 若第1片为坏芯片,则最多测试n-2次
- 若第2片为坏芯片,则最多测试n-3次;
- …
3. 分治算法
- 算法思想:假设n为偶数,将n片芯片两两一组做测试淘汰,剩下芯片构成子问题,进入下一轮分组淘汰
- 淘汰规则
- “好,好”——任留1片,进入下轮
- 其他情况——全部抛弃
- 递归出口:n
≤
\le
≤ 3
- 若为3片芯片(2好1坏),则1次测试可得到好芯片
- 若为1或2片芯片(必为好),不再需要测试
- 命题:当n是偶数时,在上述淘汰规则下,经过一轮淘汰,剩下的好芯片比坏芯片至少多1片
- 淘汰规则
- 算法思想:若n为奇数时,按上述处理可能会出问题
- 解决办法:当n为奇数时,增加一轮对轮空芯片的单独测试。
- 若该芯片为好芯片,则算法结束
- 若该芯片为坏芯片,则淘汰该芯片
- 解决办法:当n为奇数时,增加一轮对轮空芯片的单独测试。
- 伪码描述
3. 时间复杂度分析
- 设输入规模为n,每轮淘汰后,芯片数至少减半,测试次数(含轮空处理):O(n)
- 时间复杂度: W(n) = W(n/2) + O(n) , W(3)=1, W(2)=W(1)=0, 可得,W(n)=O(n)
-
分治法实例-全排列
2021-04-11 13:42:021.问题描述给出n个元素的所有可能的排列方式。如: [1,2,3]的排列有[1,2,3], [1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]1.1时间复杂度O(n!)2.算法思路我们开始有一个nums数组,其中保存着需要进行排列的数字1,2,3。...1.问题描述
给出n个元素的所有可能的排列方式。
如: [1,2,3]的排列有[1,2,3], [1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]
1.1时间复杂度
O(n!)
2.算法思路
我们开始有一个nums数组,其中保存着需要进行排列的数字1,2,3。首先从第一位开始排,第一位可选的值有三种可能即1,2或3,设置一个变量start_index=0,表示我们目前排到了第start-index位,然后分别让nums[start_index]的数字和后面几个的数字交换位置,每交换好一次,就形成了一个新的值,开始往下一位继续递归,递归完毕后需要恢复到原来的位置,再让nums[start_index]和下一位交换位置。
总结来说就是三个步骤:
① 交换元素位置
② 递归
③ 恢复元素位置
全排序.png
3.具体实现
public class Permutation {
public static List permute(int[] nums){
List perms = new ArrayList<>();
permute_recursion(nums,0,perms);
return perms;
}
private static void permute_recursion(int[] nums, int index, List list) {
int len = nums.length;
if(index == len-1){
int [] perm = new int[len];
for(int i=0;i
perm[i] = nums[i];
}
list.add(perm);
}
else{
for(int i = index;i <=len-1;i ++){
swap(nums,index,i);
permute_recursion(nums,index+1,list);
swap(nums,index,i);
}
}
}
private static void swap(int[] nums, int m, int n) {
int temp = nums[m];
nums[m]=nums[n];
nums[n] = temp;
}
}
-
分治法具体实例
2018-05-12 15:38:40分治法——见名知意,即分而治之,从而得到我们想要的最终结果。分治法的思想是将一个规模为N的问题分解为k个较小的子问题,这些子问题遵循的原则就是互相独立且与原问题相同。下面我们就用具体的例子来理解分治法的... -
算法设计与分析·分治法实例(二分归并排序)
2021-12-14 11:12:48分治法实例(二分归并排序)二分归并排序 二分归并排序就是不断地将一个序列分为两部分,分别对left序列和right序列排序,然后将两个子序列合并为新的有序序列,这个有序序列就是原问题的解,即原序列根据二分归并... -
Python分治法定义与应用实例详解
2020-09-21 05:36:36主要介绍了Python分治法定义与应用,较为详细的分析了Python分治法的概念、原理、用途,并结合实例总结了Python分治法的各种常见应用,需要的朋友可以参考下 -
分治法实例(快排)
2019-07-04 15:02:51分治法思想 分治法的精髓: 分–将问题分解为规模更小的子问题; 治–将这些规模更小的子问题逐个击破; 合–将已解决的子问题合并,最终得出“母”问题的解; 快排 快速排序原理:从一组数中选出一个pivot(中心轴... -
分治法实例:折半查找
2018-02-16 20:49:18折半查找法:对于一个有序的数列,折半查找一个元素的位置;效率:O(lgn);代码说明:①如果未找到元素a.若比所有元素小, 返回位置0b.比所有元素大,返回最后一个位置c.介于所有元素之间,返回比其大的紧邻元素的... -
分治法实例:斐波那契数列
2018-02-16 21:20:23方案四:(分治)矩阵乘法 原理:由线代知识不难证明:2x2的矩阵 {1,1,1,0} ^ n = {Fn+1,Fn,Fn,Fn-1};因此,模仿"快速幂"算法,我们很容易得出以下代码。 #include using namespace std; //二阶矩阵乘法 void ... -
分治法实例:快速幂
2018-02-16 20:59:43快速幂:即快速求幂a^b,这里提供两种实现方法:①位运算非递归实现法即将幂次b写成二进制的形式(事实上,计算机中就是以二进制保存数字的),若b的某个二进制位为1,res乘上当前的base,同时base变成base²;... -
分治法实例-找下标,下标与对应值相等
2017-11-19 22:39:47如题:设n个不同的整数排好序后存于T[1..n]中,若存在一个...笔记:一般来说如果没有时间的限制,那么O(n)遍历一遍也就出来了,但是这个要求是O(log n),所以可以考虑分治法,折半查找。#include using namespace std;i -
算法-分治法实例:循环赛日程安排问题
2015-10-12 21:09:21利用C语言实现分治法的一个实例——循环赛程问题 -
分治法实例(来自:算法:C语言实现)
2018-08-12 17:05:22使用分治法求最大值 这个函数将数组a[l]...a[r]分成a[l],...,a[m]和a[m+1],...a[r]两部分,分别求出每一部分的最大元素(递归地),并返回较大的那一个作为整个数组的最大元素.如果数组大小是偶数,则两部分大小相等;... -
C语言分治法实现归并排序
2020-12-31 22:11:38将两个及其以上的有序表合并为一张有序表,把待排序序列通过分治法分为若干个有序子序列,然后每两个子序列合并为一个子序列,经过多次合并后整合为一张有序表。 排序过程如图: 代码如下: #include stdio.h #... -
第七讲 分治法及相关实例分析
2012-11-29 13:14:10第七讲 分治法及相关实例分析 算法分析与设计 -
递归思想和案列和分治法思想的案例
2020-07-03 01:14:00递归思想和案列(阶乘函数,Fibonacci数列,Ackerman函数,整数划分问题,Hanoi塔问题)分治法思想的介绍(大整数的乘法,Strassen矩阵乘法,棋盘覆盖问题,二分搜索,快速排序,合并排序,线性时间选择)。算法课使用的ppt,可结合...