原题目
题目一:pow(x,n):
实现 pow(x, n) ,即计算 x 的 n 次幂函数。
示例 1:
输入: 2.00000, 10
输出: 1024.00000
示例 2:
输入: 2.10000, 3
输出: 9.26100
示例 3:
输入: 2.00000, -2
输出: 0.25000
解释: 2-2 = 1/22 = 1/4 = 0.25
说明:
-100.0 < x < 100.0
n 是 32 位有符号整数,其数值范围是 [−231, 231 − 1] 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/powx-n
题目二:超级次方
你的任务是计算 ab 对 1337 取模,a 是一个正整数,b 是一个非常大的正整数且会以数组形式给出。
示例 1:
输入: a = 2, b = [3]
输出: 8
示例 2:
输入: a = 2, b = [1,0]
输出: 1024
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/super-pow
题目分析
第一题:
方法一:直接法:每次都乘一次x,直到第n次结束,但这样效率不高,时间复杂度为O(n),所以优化了一下,x为1或-1.或值非常小的时候的情况,另外考虑。
方法二:使用位运算优化:将每次的次幂以1 2 4 8的形式减小,即看成二进制,每次向右移一位,让乘数每次平方,判断n的每位上的二进制是否为1,为一就将返回值乘以乘数,直到n为0为止。时间复杂度O(log2n)。
第二题:
方法一:我们发现,次方数很大且每一位存放在一个数组中,所以我们可以考虑每一位所乘之数,例如次方为个位时,乘数为a,每次乘一个a就行了,次方为十位时,每次加十乘数为a的十次方,以此类推,将每此的乘积乘起来
方法二,我们发现,任何数的次方的取余余数会形成一个循环,我们将这个循环里的数存入数组中,用次方数对循环的大小取余对应数组的数就是解
完整代码
第一题
double myPow(double x, int n){
long long int n1=fabs(n);//将n传给n1,应为n的负数部分比正数多一个,所以取绝对值后要用长整形
double res=1.0,x1;//res为最后的结果,x1为x的对应值
if(x==1||x==-1&&n%2==0)return 1;//1的任何次幂都为1,-1的次方为偶数时为1
if(x==-1&&n%2==1)return -1;//-1的次方为奇数时为-1
x1=n<0?(1/x):x;//如果次方小于0,那x的值就是x的倒数
while(n1&&res)//直到n1为0或res为0,n1为0说明乘完所有数,res为0说明res非常小,近似为0
{
res*=x1;
n1--;
}
return res;
}
double myPow(double x, int n){
long N = n;
if(n < 0) {
x = 1/x;
N = -N;
}
double base = x;
double result = 1.0;
while(N) {
if(N & 1)
result *= base;
base *= base;
N >>= 1;
}
return result;
}
第二题
int superPow(int a, int* b, int bSize){
int a1=a%1337,a2=a1;
int res=1;
for(int i=bSize-1;i>=0;i--)
{
for(int j=0;j<b[i];j++)
{
res=(res*a1)%1337;
}
for(int j=0;j<9&&i!=0;j++)
{
a1=(a1*a2)%1337;
}
a2=a1;
}
return res;
}
/*
观察2^n % 10,发现当n增加时,余数构成2、4、8、6、2的循环,循环大小为4
所以2^n%10 =2^(n%4)%10
所以a^b%1337 = (a%1337)^(b%循环大小)%1337。
用数组m储存余数循环,则mSize就是循环大小,计算b%mSize,查表m可以得到答案。
第二个循环计算b%mSize
*/
int superPow(int a, int* b, int bSize)
{
if(a == 1)
return 1;
int m[1339], mSize, x;
mSize = 0;
m[1] = 0;
m[0] = 1;
a = a % 1337;
x = a;
while(x != m[1])
{
m[++mSize] = x;
x = x * a % 1337;
}
x = 0;
for(int i = 0; i < bSize; i++)
{
x = (10 * x + b[i]) % mSize;
}
return m[x];
}
总结
掌握数学思维