【46-50】劍指offer

46.題目描述

每年六一兒童節,牛客都會準備一些小禮物去看望孤兒院的小朋友,今年亦是如此。HF作爲牛客的資深元老,自然也準備了一些小遊戲。其中,有個遊戲是這樣的:首先,讓小朋友們圍成一個大圈。然後,他隨機指定一個數m,讓編號爲0的小朋友開始報數。每次喊到m-1的那個小朋友要出列唱首歌,然後可以在禮品箱中任意的挑選禮物,並且不再回到圈中,從他的下一個小朋友開始,繼續0...m-1報數....這樣下去....直到剩下最後一個小朋友,可以不用表演,並且拿到牛客名貴的名偵探柯南典藏版(名額有限哦!!^_^)。請你試着想下,哪個小朋友會得到這份禮品呢?(注:小朋友的編號是從0n-1)

思路:1.採用循環鏈表的方式實現

      2.通過數學推導,得出遞歸公式,然後按照遞歸公式編寫

      具體實現見代碼:

#include <iostream>

#include <list>

using namespace std;

 

class Solution {

public:

       //鏈表實現

   int LastRemaining_Solution(unsigned int n, unsigned int m)

    {

              //檢查輸入是否合法

              if(n< 1 || m < 1)

                     return-1;

 

       list<int> lList(n);

              list<int>::iteratorite = lList.begin();

              //初始化鏈表

              inti = 0;

              for(;ite != lList.end(); ite++)

                     *ite= i++;

 

              //循環刪除鏈表

              ite= lList.begin();

 

              while(lList.size()> 1)

              {

                     for(i= 1; i < m; i++)

                     {

                            ite++;

                            if(ite== lList.end())

                                   ite= lList.begin();

                     }

 

                     list<int>::iteratoriteTemp = ++ite;

                     if(iteTemp== lList.end())

                            iteTemp= lList.begin();

 

                     lList.erase(--ite);

                     ite= iteTemp;

              }

              returnlList.front();

    }

 

       //數學推導實現

       intLastRemaining_Solution1(unsigned int n, unsigned int m)

    {

              if(n<1|| m < 1)

                     return-1;

 

              intlast = 0;

              for(inti = 2; i <= n; i++)

                     last= (last + m)%i;

              returnlast;

       }

};

 

int main()

{

       Solutions;

       cout<<s.LastRemaining_Solution(10,30)<<endl;

       cout<<s.LastRemaining_Solution1(10,30)<<endl;

      

       return0;

}

 

47.題目描述

1+2+3+...+n,要求不能使用乘除法、forwhileifelseswitchcase等關鍵字及條件判斷語句(A?B:C)。

#include<iostream>

using namespace std;

 

class Solution {

private:

       staticint nN;

       staticlong int nSum;

public:

       //構造函數中實現自加

       Solution()

       {

              nN++;

              nSum+= nN;

       }

       //重置nN和nSum

       staticvoid Reset()

       {

              nN= 0;

              nSum= 0;

       }

       //返回求和結果

       staticlong int GetSum()

       {

              returnnSum;

       }

       //求前n項和

   int Sum_Solution(int n)

       {

              Solution::Reset();

 

              Solution*temp = new Solution[n];

              delete[] temp;

              temp= NULL;

                    

              returnSolution::GetSum();

    }

};

 

int Solution::nN = 0;

long int Solution::nSum = 0;

 

int main()

{

       Solutions;

       cout<<s.Sum_Solution(100)<<endl;

      

       return0;

}

 

48.題目描述

寫一個函數,求兩個整數之和,要求在函數體內不得使用+-*/四則運算符號。

 

#include <iostream>

using namespace std;

 

class Solution {

public:

   int Add(int num1, int num2)

    {

              intnSum, nCarry;

              do

              {

                     nSum= num1 ^ num2;

                     nCarry= (num1 & num2)<<1;

 

                     num1= nSum;

                     num2= nCarry;

              }while(num2 != 0);

 

              returnnum1;

    }

};

 

int main()

{

       Solutions;

       cout<<s.Add(100,55)<<endl;

      

       return0;

}

 

49.題目描述

將一個字符串轉換成一個整數,要求不能使用字符串轉換整數的庫函數。

    注意:仔細考略一些輸入不合法情況的處理。

#include <iostream>

using namespace std;

 

enum IsValid{VALID = 0, INVALID};

IsValid flagError = VALID;

 

class Solution {

public:

   int StrToInt(string str)

       {

              //處理字符串"",輸入不合法"!*"的情況,第一個字符爲'+'或者爲'-'表示輸入爲正負數

              if(str.size()==0)

              {

                     flagError= INVALID;

                     return0;

              }

 

              intflag = 1; //1 表示正數,-1表示負數

              flagError= VALID;

              char*pStr = &str[0];

             

              for(inti = 0; i < str.size(); i++)

              {

                     if(i== 0)

                     {

                            if(str[i]== '+')

                            {

                                   pStr++;

                                   flag= 1;

                                   continue;

                            }

                            if(str[i]== '-')

                            {

                                   pStr++;

                                   flag= -1;

                                   continue;

                            }

                     }

                     if(str[i]> '9' || str[i] < '0')

                     {

                            flagError= INVALID;

                            return0;

                     }

              }

             

              returnStrToInt(pStr, flag);

    }

      

       intStrToInt(char *pStr, int NePoFlag)

       {

              intnumber = 0;

              while(*pStr!= '\0')

              {

                     number= number*10 + NePoFlag*(*pStr-'0');

                     pStr++;

              }

 

              returnnumber;

       }

};

 

int main()

{

       Solutions;

       cout<<s.StrToInt("+1232")<<endl;

       cout<<s.StrToInt("-132")<<endl;

       cout<<s.StrToInt("+1da2")<<endl;

       cout<<s.StrToInt("")<<endl;

       cout<<s.StrToInt("1232")<<endl;

 

       return0;

}

 

50.題目描述

在一個長度爲n的數組裏的所有數字都在0n-1的範圍內。數組中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出數組中任意一個重複的數字。例如,如果輸入長度爲7的數組{2,3,1,0,2,5,3},那麼對應的輸出是重複的數字2或者3

思路:因爲數組元素是在0-n-1範圍內,那麼若排序後i位置的值爲i,那麼數組不存在重複的數字,否則存在重複的數字。

 

#include <iostream>

using namespace std;

 

class Solution {

public:

   // Parameters:

   //        numbers:     an array of integers

   //        length:      the length of array numbers

   //        duplication: (Output)the duplicated number in the array number

   // Return value:       true if theinput is valid, and there are some duplications in the array number

   //                     otherwisefalse

   bool duplicate(int numbers[], int length, int* duplication)

       {

              //如果數組爲NULL,則返回

              if(numbers== NULL || length < 1)

                     returnfalse;

      

              for(inti = 0; i < length; i++)

              {

                     while(numbers[i]!= i)

                     {

                            if(numbers[i]== numbers[numbers[i]])

                            {

                                   *duplication= numbers[i];

                                   returntrue;

                            }

                            inttemp = numbers[i];

                           

                            numbers[i]= numbers[numbers[i]];

                            numbers[temp]= temp;

                     }

              }

       return false;

    }

};

 

int main()

{

       intarray[] = {2,3,1,0,2,5,3};

       Solutions;

       intdup;

       if(s.duplicate(array,7, &dup))

       {

              cout<<"存在重複的數字"<<endl;

              cout<<dup<<endl;

       }

       else

              cout<<"不存在重複的數字"<<endl;

 

       return0;

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章