【剑指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);
}
posted @ 2020-04-23 13:05  NaughtyCoder  阅读(136)  评论(0)    收藏  举报