剑指Offer - 面试题16:数值的整数次方

简介: 剑指Offer - 面试题16:数值的整数次方

题目

实现函数double Power(double base, int exponet),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。


分析

暴力法

exponet次方,循环exponet次就可以了。时间复杂度为O(n),O(1);

C

#include<stdio.h>
#include<stdlib.h>
//暴力法
double Power(double base, int exponent)
{
  int i = 0;
  double sum = 1;
  for (i = 0; i < exponent; i++)
  {
    sum *= base;
  }
  return sum;
}
int main()
{
  printf("2^3=%f\n", Power(2, 3));
  return 0;
}


递归法

我们可以得出公式:baseexponet = base exponet-1;复杂度不变,但是写法比较优雅。

C

#include<stdio.h>
#include<stdlib.h>
//递归
double Power(double base, int exponent)
{
  if (exponent == 0)
  {
    return 1;
  }
  return Power(base, exponent - 1) * base;
}
int main()
{
  printf("2^3=%f\n", Power(2, 3));
  return 0;
}


但是上面俩种方法都存在一种隐藏危险,如果输出负数怎么办???

所以我们要把所有情况都考虑进来比如,base=0,exponent为负数,小数,零等。

优化的暴力法

C

#include<stdio.h>
#include<stdlib.h>
double Power(double base, double exponent)
{
  if (base == 0 || exponent < 0)//exponent < 0
  {
    return -1;
  }
  int flag = 1;//记录exponent正负,1表示大于1,-1表示在0-1直接
  int i = 0;
  double sum = 1;
  if (exponent < 1 && exponent > 0)//0 <  exponent < 1
  {
    exponent = 1.0 / exponent;
    flag = -1;
  }
  for (i = 0; i < exponent; i++)
  {
    sum *= base;
  }
  if (flag == -1)//如果exponent本身是小数就求倒数
  {
    sum = 1.0 / sum;
  }
  return sum;
}
int main()
{
  printf("2^3=%f\n", Power(2, 3));
  return 0;
}


公式+递归

如果求216,可以转换为求28 * 28;28 = 24*24;24 = 22 * 22;22 = 21 * 21;

同理求215,215 = 27*28;28又等价于上面得到计算,这里我们只算27;27=24*23;23=21*22;

我们还可以优化215。215 = 2 * 2 7 * 27;把那个奇数单独拿出来。

根据上面的规律我们可以列一个公式


我们根据公式实现递归算法。

时间复杂度为O(log2n),空间复杂度为O(1);

C

#include<stdio.h>
#include<stdlib.h>
//这里的exponent是整数哦
double PowerRecursion(double base, int exponent)//递归计算  
{
  if (exponent == 0)
  {
    return 1;
  }
  if (exponent == 1)
  {
    return base;
  }
  double sum = PowerRecursion(base, exponent >> 1);
  sum *= sum;
  if (exponent % 2 == 1)//只要是奇数,就在单独乘一次。
  {
    sum *= base;
  }
  return sum;
}
double Power(double base, double exponent)
{
  if (base == 0 || exponent < 0)//exponent < 0
  {
    return -1;
  }
  int flag = 1;//记录exponent正负,1表示大于1,-1表示在0-1直接
  int i = 0;
  double sum = 1;
  if (exponent < 1 && exponent > 0)//0 <  exponent < 1
  {
    exponent = 1.0 / exponent;
    flag = -1;
  }
  sum = PowerRecursion(base, (int)exponent);
  if (flag == -1)//如果exponent本身是小数就求倒数
  {
    sum = 1.0 / sum;
  }
  return sum;
}
int main()
{
  printf("2^3=%f\n", Power(2, 3));
  return 0;
}

本章完!


目录
相关文章
|
5月前
|
搜索推荐 索引 Python
【面试题】缺失的第一个整数
【面试题】缺失的第一个整数
49 0
|
5月前
|
安全 编译器 C++
【剑指offer】2.2编程语言(p22-p25)——面试题1:string赋值运算函数
【剑指offer】2.2编程语言(p22-p25)——面试题1:string赋值运算函数
|
8月前
【一刷《剑指Offer》】面试题 23:从上往下打印二叉树
【一刷《剑指Offer》】面试题 23:从上往下打印二叉树
|
8月前
【一刷《剑指Offer》】面试题 22:栈的压入、弹出系列
【一刷《剑指Offer》】面试题 22:栈的压入、弹出系列
|
8月前
|
算法
【一刷《剑指Offer》】面试题 21:包含 main 函数的栈
【一刷《剑指Offer》】面试题 21:包含 main 函数的栈
|
8月前
【一刷《剑指Offer》】面试题 20:顺时针打印矩阵
【一刷《剑指Offer》】面试题 20:顺时针打印矩阵
|
8月前
【一刷《剑指Offer》】面试题 19:二叉树的镜像
【一刷《剑指Offer》】面试题 19:二叉树的镜像
|
8月前
【一刷《剑指Offer》】面试题 18:树的子结构
【一刷《剑指Offer》】面试题 18:树的子结构
|
8月前
【一刷《剑指Offer》】面试题 17:合并两个排序的链表
【一刷《剑指Offer》】面试题 17:合并两个排序的链表
|
8月前
【一刷《剑指Offer》】面试题 16:反转链表
【一刷《剑指Offer》】面试题 16:反转链表