剑指offer 66题 part2(7~12题)

第七题:斐波那契数列

a0=0

a1=1

a2=1

a3=2

......

an=an-1+an-2

代码:

class Solution {
public:
    int Fibonacci(int n) {
        int a[50];
        a[0]=0;
        a[1]=1;
        for(int i=2;i<=n;i++)
            a[i]=a[i-1]+a[i-2];
        return a[n];
    }
};

第八题:跳台阶

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

题解:找规律,发现是一个斐波那契数列

代码:

class Solution {
public:
    int jumpFloor(int number) {
        if(number<=0) return 0;
        if(number==1) return 1;
        if(number==2) return 2;
        int a=1,b=2,t;
        number-=2;
        while(number--){
            t=b;
            b=a+b;
            a=t;
        }
        return b;
    }
};

第九题:变态跳台阶

一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

题解:

找规律,发现答案是 2^n

class Solution {
public:
    int jumpFloorII(int number) {
        return pow(2,number-1);
    }
};

第十题:矩形覆盖

我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?

题解:找规律,发现还是一个斐波那契数列

代码:

class Solution {
public:
    int rectCover(int number) {
        if(number<=0) return 0;
        if(number==1) return 1;
        if(number==2) return 2;
        int t,a=1,b=2;
        number-=2;
        while(number--){
            t=b;
            b=a+b;
            a=t;
        }
        return b;
    }
};

第十一题:二进制中 1 的个数

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

题解:把数据化为它的补码

正数的补码==反码==原码

负数的补码==反码+1

负数的反码==原码除了符号位后每一位取反

需要注意的是:最小的负数的补码,在反码加一后会溢出,变成全0,此时人为规定最高位为 1

代码1:

class Solution {
public:
     int  NumberOf1(int n) {
         int a[40],t=n,p=0;
         if(n<0) a[31]=1,t=-t;
         for(int i=0;i<31;i++){
             if(t%2) a[i]=1;
             else    a[i]=0;
             t/=2;
         }
         int index=0;
         if(n<0){
             index=1;
             for(int i=0;i<31;i++)
                 a[i]=a[i]?0:1;
             for(int i=0;i<=31;i++){
                 if(index==0) break;
                 if(a[i]) a[i]=0;
                 else a[i]=1,index=0;
             }
         }
         
         int cnt=0;
         if(index) return 1;
         for(int i=0;i<=31;i++)
             if(a[i]) cnt++;
         return cnt;
     }
};

代码2:

通过一个无符号数字,依次和数 n 与运算得到最后答案

int cnt=0;
unsigned int flag = 1;
while(flag){
if(n&flag)
      cnt++;
      flag = flag<<1;
}
return cnt;

代码3:

链接:https://www.nowcoder.com/questionTerminal/8ee967e43c2c4ec193b040ea7fbb10b8
来源:牛客网

如果一个整数不为0,那么这个整数至少有一位是1。如果我们把这个整数减1,那么原来处在整数最右边的1就会变为0,原来在1后面的所有的0都会变成1(如果最右边的1后面还有0的话)。其余所有位将不会受到影响。
举个例子:一个二进制数1100,从右边数起第三位是处于最右边的一个1。减去1后,第三位变成0,它后面的两位0变成了1,而前面的1保持不变,因此得到的结果是1011.我们发现减1的结果是把最右边的一个1开始的所有位都取反了。这个时候如果我们再把原来的整数和减去1之后的结果做与运算,从原来整数最右边一个1那一位开始所有位都会变成0。如1100&1011=1000.也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数的二进制有多少个1,就可以进行多少次这样的操作

class Solution {
public:
     int  NumberOf1(int n) {
         int cnt=0;
         while(n){
             n=n&(n-1);
             cnt++;
         }
         return cnt;
     }
};


第十二题:数值的整数次方

给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。

代码1:利用快速乘方思想,矩阵快速幂同样有这种思想

class Solution {
public:
    double Power(double base, int exponent) {
        double ans=1;
        int x=exponent;
        if(x==0) return 1;
        if(x<0) x=-x;
        
        while(x){
            if(x&1) ans*=base;
            base*=base;
            x>>=1;
        }
        ans=exponent>0?ans:1.0/ans;
        return ans;
    }
};

代码2:直接利用函数

class Solution {
public:
    double Power(double base, int exponent) {
        return pow(base,exponent);
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章