背景
腾讯后台开发岗位的第三次面试中,面试官问到了如下的题目:
给定一个函数原型如下
float cubicRoot(float num, float maxRange) { }
需要完成该函数,该函数的作用是计算一个浮点数的三次立方根,且结果需要满足maxRange这个范围的误差
思路
这个题目面试官其实考察的是使用二分的做法来逼近目标值,因为在[1,+∞)
的范围内的话,f(x)=x^3
是单调递增的,因此确立一个上下界,最简单就是以l = 0, r = targetNum
为上下界,每次判断中间值的三次方与目标值的大小关系,从而判断接下来的步骤。
但是这样存在着以下的一些问题:
- 若目标值的范围在
(-∞,0]
这个范围,变成了单调递减函数 - 若目标值的范围在
(-1,1)
这个范围内的话,一个数字的立方根只会更加小 - 精度问题
针对这些问题,依次又有以下的解决方案:
- 将所有数字统一为正数处理,之后返回结果的时候再看目标数字如果是负数则返回一个负数结果,因为立方计算不会导致符号的变化
[0,1)
这个范围内的话,上下界确定为l = taregtNum, r = 1
即可,其余不用变化- 改用
double
计算中间结果
最终的代码以及测试代码如下:
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cassert>
using namespace std;
template<typename T>
T abs(T a) {
if (a < 0) return -a;