[微软面试100题]61-70
生活随笔
收集整理的這篇文章主要介紹了
[微软面试100题]61-70
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
第六十一題:找出整型數(shù)組中兩個(gè)只出現(xiàn)了一次的數(shù)(其余都出現(xiàn)了兩遍)
思路:凡是涉及到出現(xiàn)了兩次,出現(xiàn)了一次的都用XOR。把所有的數(shù)都XOR一遍得到一個(gè)數(shù)tmp,這個(gè)數(shù)就是要得到的兩個(gè)數(shù)的XOR。tmp肯定不為0,因?yàn)檫@要得的兩個(gè)數(shù)一定不相等。則使用tmp為1的位可以把原數(shù)組分為兩組。因?yàn)檫@兩個(gè)數(shù)的這一位一定不同(1^0=1),所以這兩個(gè)數(shù)一定各自落在一個(gè)組里,而出現(xiàn)了兩次的同一個(gè)數(shù)也會(huì)在同一組里。重新對(duì)各個(gè)組XOR一編即可找到這個(gè)組中唯一出現(xiàn)一次的數(shù)了。整個(gè)過(guò)程遍歷了兩次數(shù)組,復(fù)雜度O(2n)=O(n) void twoSingleNum(const int *a,int cnt){int tmp=0;for(int i=0;i<cnt;++i) tmp^=a[i];//比較短的時(shí)候放后面int mark=1;while( (tmp&mark)==0)mark<<=1;// mark<<1 has no effect on markint num1=0,num2=0;for(int i=0;i<cnt;++i)(a[i]&mark)==0 ? num1^=a[i] : num2^=a[i];//must have (), &'s priority is very low.cout<<num1<<" "<<num2<<endl; }第六十三題:刪除字符串中的特定字符
思路:定義兩個(gè)指針slow和fast,如果fast不是要?jiǎng)h的字符則*slow=*fast,++fast,++slow;否則只++fast跳過(guò)要?jiǎng)h的字符。相當(dāng)于把字符串復(fù)制一遍,只不過(guò)跳過(guò)了要?jiǎng)h的字符。復(fù)雜度O(n) void delChars(char s[],const char *chars){int hash[256];memset(hash,0,sizeof(int)*256);while(*chars!='\0'){hash[int(*chars)]=1;chars++;}char *pFast=s,*pSlow=s;while(*pFast!='\0'){if(hash[int(*pFast)]==0){*pSlow=*pFast;pSlow++;}pFast++;//相當(dāng)于把不刪的復(fù)制到前面的slow,刪的就跳過(guò) }*pSlow='\0'; }第六十四題:尋找丑數(shù)(從小到大打印1500個(gè)丑數(shù))
丑數(shù)是因式全由 2 3 5組成的數(shù)。如果逐個(gè)因式分解效率爆低。使用動(dòng)態(tài)規(guī)劃的思想,后一個(gè)丑數(shù)肯定是前面丑數(shù)的min(2倍 3倍 5倍)且剛好大于前面一個(gè)丑數(shù)。可以把已經(jīng)算好的丑數(shù)記錄在數(shù)組中。然后找到前面某個(gè)丑數(shù)的2倍剛好大于最后一個(gè)丑數(shù)的,再找3倍、5倍。這三個(gè)數(shù)的最小者就是下一個(gè)丑數(shù)。可用三個(gè)指針來(lái)從前往后尋找。 void generateUglyNum(int n){int buf[n+10];buf[0]=1;buf[1]=2;buf[2]=3;buf[3]=4;buf[4]=5;int *p2=buf,*p3=buf,*p5=buf;for(int i=5;i<n;++i){while(*p2*2<=buf[i-1])p2++;unsigned int c1=*p2*2;while(*p3*3<=buf[i-1])*p3++;unsigned int c2=*p3*3;while(*p5*5<=buf[i-1])*p5++;unsigned int c3=*p5*5;if(c1<=c2 && c1<=c3)buf[i]=c1;if(c2<=c1 && c2<=c3)buf[i]=c2;if(c3<=c1 && c3<=c2)buf[i]=c3;cout<<i+1<<":"<<buf[i]<<endl;}第六十五題:輸出1到最大的N位數(shù)
void helper(int n){int tmp=0;for(int i=0;i<n;++i){tmp+=9;if(i!=n-1)tmp*=10;}for(int i=1;i<=tmp;++i){cout<<i<<" ";}cout<<endl; }第六十六題:利用遞歸翻轉(zhuǎn)一個(gè)棧
利用遞歸可以把棧元素一個(gè)一個(gè)拿出來(lái),進(jìn)行某種操作后一個(gè)一個(gè)放回去。利用這種規(guī)律可以先把棧元素拿出來(lái),放回去的時(shí)候每個(gè)元素都沉到最底。如何沉到最底也是利用遞歸。 template <class T> void reverse_stack_recursive(stack<T> &s){if(!s.empty()){T tmp=s.top();s.pop();reverse_stack_recursive(s);//從頂?shù)降滓粋€(gè)一個(gè)拿開(kāi)putToButtom(s,tmp);//從棧最低的元素一個(gè)一個(gè)放回,但是每次都返回棧底 } }template <class T>//這是一種棧的常用操作,先拿出來(lái),再放回去 void putToButtom(stack<T> &s,T &tmp){if(s.empty()){s.push(tmp);//拿到?jīng)]有了,就放這個(gè)目標(biāo)元素到棧底return;}T o=s.top();//將棧里的元素一個(gè)一個(gè)拿開(kāi) s.pop();putToButtom(s,tmp);//直到棧為空,放進(jìn)目標(biāo)元素s.push(o);//再一個(gè)一個(gè)放回去 }第六十七題:撲克牌順序
一開(kāi)始用了一個(gè)麻煩的方法,就是想挑出所有不合法的情況(盡量避免這種思路,因?yàn)椴缓戏ǖ那闆r會(huì)隨著思考的深入變得越來(lái)越多),最后就是合法的了。但不合法情況的組合比較多,容易漏。 好的方法是用量值來(lái)統(tǒng)籌所有情況,把王當(dāng)做一種可以填充gap的東西,一個(gè)王填一個(gè)gap。如果可以用的王用完了,或者有兩張牌一樣的情況就是不合法了。 int has_gap(int a[],int l,int allowGaps){for(int i=1;i<5-l;++i){//不同王數(shù)for的長(zhǎng)度不一,這里用一個(gè)參數(shù)來(lái)傳遞for的長(zhǎng)度就可以實(shí)現(xiàn)代碼重用,不用寫(xiě)3個(gè)for了。if(a[i]-a[i-1]==0)return 0;allowGaps-=a[i]-a[i-1]-1;}if(allowGaps<0)return 0;return 1; }int is_sequence_good(int a[]){//14 is the kingsort(a,a+5);if(a[3]==14 && a[4]==14)return has_gap(a,2,2);//double kingselse if(a[4]==14)return has_gap(a,1,1);else return has_gap(a,0,0); }第六十七題:打印出n粒骰子的點(diǎn)數(shù)和的出現(xiàn)概率
思路:每種搭配出現(xiàn)的概率都是1/6^n,因此問(wèn)題轉(zhuǎn)移到每種和存在多少種搭配?如3+3=2+4=1+5,兩粒骰子的時(shí)候和6時(shí)就5種情況(2,4 1,5可調(diào)轉(zhuǎn)) 使用動(dòng)態(tài)規(guī)劃非常簡(jiǎn)單,關(guān)鍵是公式:f(s,n)=f(s-1,n-1)+f(s-2,n-1)+f(s-3,n-1)+f(s-4,n-1)+f(s-5,n-1)+f(s-6,n-1),s為n粒骰子的和。 解釋:n粒骰子和為s出現(xiàn)的次數(shù),等于n-1粒時(shí),s分別減少1到6時(shí)的次數(shù)之和。就是概率上的全概率的意思。 void showDicePro(int n){#define DICE_NUM 6 //為以后擴(kuò)展做準(zhǔn)備,注意擴(kuò)展性可以給面試官好印象int p[n][DICE_NUM*n+1];memset(p,0,sizeof(int)*(DICE_NUM*n+1)*n);for(int j=1;j<=DICE_NUM;++j) p[0][j]=1;//初始化1顆骰子的情況for(int i=1;i<n;++i)for(int j=1;j<=DICE_NUM*n;++j)for(int k=j-DICE_NUM;k<j;++k)if(k>=0) p[i][j]+=p[i-1][k];//n粒的情況DP n-1的for(int i=1;i<=DICE_NUM*n;++i) cout<<p[n-1][i]<<" ";cout<<endl; }第六十八題:把數(shù)組組成最小的數(shù)
思路1:建立一個(gè)比較函數(shù)判斷兩個(gè)數(shù)應(yīng)該放前放后。從最高位開(kāi)始比較,如果某一位比較小則放前。如果長(zhǎng)度不等,多出來(lái)的位與前面的位依次對(duì)比,詳細(xì)看代碼。 思路2:此法簡(jiǎn)單。借用字符串比較兩個(gè)數(shù)的前后順序。如"ab">"ba"的話,則a放b前,即a<b。由于ab拼接的兩個(gè)字符串長(zhǎng)度一定相等,直接使用string的<即可判斷。 PS:1、sort的比較函數(shù)的意思就是第一個(gè)參數(shù)放第二個(gè)參數(shù)前面的話就true。2、sprintf的用法:可以先用char[]來(lái)格式化字符串,然后直接用string的構(gòu)造函數(shù)string(char*)來(lái)轉(zhuǎn)化(string沒(méi)有format函數(shù))。 bool fronter(int a,int b){//思路1vector<int> va,vb,tmp;while(a!=0){tmp.push_back(a%10);a/=10;}while(!tmp.empty()){va.push_back(tmp.back());tmp.pop_back();}while(b!=0){tmp.push_back(b%10);b/=10;}while(!tmp.empty()){vb.push_back(tmp.back());tmp.pop_back();}//比較長(zhǎng)度int lena=va.size();int lenb=vb.size();int i=0,j=0;while(i<lena || j<lenb){if(va[i]<vb[j] && i<lena && j<lenb)return true;if(va[i]>vb[j] && i<lena && j<lenb)return false;if(i==lena && j==lenb)return false;if(i==lena && j!=lenb){//前面的放前面就是trueif(vb[j]>vb[j-lena])return true;//短在前else if(vb[j]<vb[j-lena]) return false;}//多出來(lái)的位與第一位比if(i!=lena && j==lenb){if(va[i]>va[i-lenb])return false;//短在前else if(va[i]<va[i-lenb])return true;}if(i<lena)++i;if(j<lenb)++j;}return true; }bool helper(int a,int b){//思路2char sa[50],sb[50];sprintf(sa,"%d",a);sprintf(sb,"%d",b);string stra(sa),strb(sb);return stra+strb<strb+stra; }void final(int *num,int n){vector<int> a;for(int i=0;i<n;++i)a.push_back(num[i]);sort(a.begin(),a.end(),helper);for(unsigned int i=0;i<a.size();++i){cout<<a[i];}cout<<endl; }第六十九題:旋轉(zhuǎn)數(shù)組中的最小數(shù)
思路1:直接從左往右掃,碰到右比左小的就是最小數(shù)。沒(méi)有的話第一個(gè)就是最小數(shù)。 思路2:參照二分查找。如果有旋轉(zhuǎn),最小數(shù)一定在旋轉(zhuǎn)那。 void helper(int *a,int n){if(n==2){if(a[0]>a[1])cout<<a[1]<<endl;else cout<<a[0]<<endl;return;}int mid=n/2;if(a[0]>a[mid])helper(a,mid+1);//有旋轉(zhuǎn)else if(a[mid]>a[n-1])helper(a+mid,n-mid);//有旋轉(zhuǎn)else if(a[0]<a[mid])helper(a,mid+1);//沒(méi)旋轉(zhuǎn)else helper(a+mid,n-mid);//沒(méi)旋轉(zhuǎn) }?
轉(zhuǎn)載于:https://www.cnblogs.com/iyjhabc/archive/2013/03/28/2986020.html
總結(jié)
以上是生活随笔為你收集整理的[微软面试100题]61-70的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 27 款经典的CSS 框架
- 下一篇: oracle status