注:本题不是必须使用递归的方法来求解的,同时,2的幂也可以用pow函数来代替;但笔者在此讲解会是在不用pow函数情况下,使用递归的方式
本题使用递归时,首先考虑的是如何实现2的幂数,笔者在这边又再题目给的函数基础上,又自定义了一个长整型函数mi(这边的返回类型必须是long int,否则使用递归以后会由于返回值超过int字节大小的范围,出现栈溢出),然后在该函数中实现与pow函数相同功能的函数。
long int mi(int x)
{
if(x==0)
return 1;
else
return 2*mi(x-1);
}
递归代码解释:
假设x=3,当x=3时,执行return 2*mi(x-1)这一语句,开始递归;这边就是返回2*mi(2),而mi(2)即是x=2时,执行return 2*mi(x-1)这一语句,即返回2*mi(1);mi(1)即是x=1时,执行return 2*mi(0)。mi(0)是x=0,那么在if-else语句中,执行前者return 1,可以看成mi(0)=1,返回了1给return 2*mi(0);然后2*mi(0)返回给了mi(1)这一函数,可以看成mi(1) = 2*mi(0) = 2,返回了2给return 2*mi(1),诸如此,不难看出mi(2) = 4,mi(3) = 8;而题目在传参时是假设了传来的是x = 3,因此8即是我们所求,返回的值也是8。
像这样的代码实现了与pow函数相同功能
然后在题目给出的bool isPowerOfTwo(int n)函数中,实现n和2的大小判断,只要n=2的幂数,就返回true,否则返回false。
首先由于2的0次方为1 ,因此在n等于1时,这种情况应单独罗列出来,并返回true
if(n==1)
return true;
其他情况笔者拆分成两个问题的:
1.我应该如何判断n是否为2的幂数
2.true和false两种情况我应该如何返回时不相干
对于第一个问题,笔者是用到了循环判断,并定义了一个整型变量x=1,用作我mi函数的参数,每次循环让x++,判断n是否等于mi(x)。
对于第二个问题,首先读者需要明白一件事,那就是n<mi(x)时,n不可能为2的幂数,由于n是给定的,x从1开始增大,所以当mi函数返回值比n大以后,幂函数返回值只会无限增大,即n恒小于mi(x),那么此时n不可能是2的幂数。所以在n<mi(x)时就可以在循环中直接return false,无需加上break跳出循环(自定义函数中出现return xxx后,本次函数调用就直接结束了;只是本次函数调用结束了,递归中是又一次调用了这个函数本身,请勿以为下一次函数调用也一同结束了!)
将上述两个问题解决以后,我们开始考虑循环跳出条件,笔者这里用到了n!=mi(x),此时n一定是2的幂数才跳出了循环,所以直接在循环语句后加上return true即可。
else
{
while(n!=mi(x))
{
x++;
if(n<mi(x))
return false;
}
return true;
}
如上,题目就被解开了。撒花撒花
写在最后:本题使用递归方法并不是最优解,因此读者在做本题时可以尝试其他方法。同时leetcode的326题:3的幂,以及leetcode的342题:4的幂使用的是相同方法
——————————————————分割线——————————————————————
pow函数的用法:
int ret = pow(x,y)即是ret =
同时在使用pow函数时需要引用头文件,#include<math.h>
函数递归详细介绍:函数递归复习
简单难度递归相关leetcode题目链接(无链表):
1. leetcode第五百零九题:斐波那契数(C语言)
2. leetcodeLCR 187题:破冰游戏(C语言+约瑟夫环)