【剑指offer】【位运算】64. 求1+2+…+n
题目链接:https://leetcode-cn.com/problems/qiu-12n-lcof/
位运算
本题要求不使用乘除法,for/while/if/else/switch/case等关键字及条件判断语句;
使用递归来做,通常递归中条件的结束需要用到if,本题可以利用逻辑与的“短路”完成本题。
n > 1 && sumNums(n - 1)
当n > 1为true是,执行sumNums(n - 1);
否则,n > 1为false,递归结束。
class Solution {
public:
int res = 0;
int sumNums(int n) {
bool x = n > 1 && sumNums(n - 1);
res += n;
return res;
}
};
构造函数
利用构造函数求解,从循环角度考虑,循环只是让相同的代码重复执行n遍,可以通过定义一个类型,然后创建n个该类型的实例,这样,这个类型
的构造函数就会被调用n次,可以将累加相关的代码放到构造函数中;
class Temp
{
public:
Temp() {++N; Sum += N;}
static void Reset(){N = 0; Sum = 0;}
static unsigned int GetSum() {return Sum;}
private:
static unsigned int N;
static unsigned int Sum;
};
unsigned int Temp::N = 0;
unsigned int Temp::Sum = 0;
class Solution {
public:
int sumNums(int n) {
Temp::Reset();
Temp *a = new Temp[n];
delete[]a;
a = nullptr;
return Temp::GetSum();
}
};
虚函数
利用虚函数,从递归角度考虑,不能再一个函数判断是不是该终止递归,我们定义两个函数,一个函数为递归函数,另一个函数处理终止递归的情况
需要在这两个函数里二选一,从二选一容易想到bool变量,值为true时,调用第一个函数,值为false的时候调用第二个函数。关键在于如何把数值
n转换成布尔值:对n连续做两次反运算,即!!n。非0转换的n转化为true,0转化为false
class A;
A* Array[2];
class A
{
public:
virtual unsigned int Sum (unsigned int n)
{
return 0;
}
};
class B: public A
{
public:
virtual unsigned int Sum (unsigned int n)
{
return Array[!!n]->Sum(n-1) + n;
}
};
class Solution {
public:
int sumNums(int n) {
A a;
B b;
Array[0] = &a;
Array[1] = &b;
int value = Array[1] -> Sum(n);
return value;
}
};
函数指针
typedef unsigned int (*fun)(unsigned int);
unsigned int Teminator(unsigned int n)
{
return 0;
}
int sumNums(int n){
static fun f[2] = {Teminator, sumNums};
return n + f[!!n](n - 1);
}
知识的价值不在于占有,而在于使用