劍指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);
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章