馬上就要到9月份了,意味着一年一度的秋招就要開始了,相信不論是正在實習的童鞋還是馬上就要找工作的童鞋,BAT無疑是國內的“明星企業”,是每個學計算機的小夥伴們心之嚮往的企業,但是呢?對於進BAT來講,即使你項目經驗非常豐富,想進BAT,還有一道門檻要過那就是算法面試,尤其是想去百度的小夥伴們,那算法必須得考,也是面試中的重點。
說實話,對於算法這個東西,真的得靠天賦的,不是像項目那樣,你多做多動手自然就會,雖然要靠天賦,但是對於基本的算法以及基本的算法面試題我們還是可以通過多積累多思考來培養自己的解題思路。本博客就是通過講解BAT算法面試中的一些具備代表性的題來教大家如何去慢慢的積累算法方面的解題思路。
題目描述:給一個正整數n,打印出所有的和爲n的連續正整數序列,如果不存在則輸出空,如:n=15,因爲15=1+2+3+4+5=4+5+6=7+8則輸出[1,2,3,4,5],[4,5,6],[7,8]
其實對於算法基礎比較好的童鞋來說這道題不算難,但是在面試那種環境下,小夥伴們可能因爲緊張或者其他原因,在面試現場規定的時間內寫出正確的程序也不是一件很簡單的事,因此我們不妨從一些簡單的例子入手,一點一點的分析,這樣可能解題思路就打開了。
對於本題,如果在面試時一時想不出來,可以先考慮一種自己平時遇到的簡單的但和此題情況相類似的題目思考一下,如在一個給定的遞增的數組中選取兩個數使得其和等於n,存在則輸出這兩個數,不存在則輸出空。對於這道題則太簡單了,我們都知道可以定義兩個指針start與end,剛開始時start指向數組中的最小的元素(即第一個元素),end指向數組中的最大元素(即最後一個元素),然後判斷start+end的和sum是否爲n,如果是則輸出start與end的值,如果sum>n則說明我們應該丟去sum中較大的值end,而選一個比end小的值,即array[end--],反之如果sum<n則說明我們應該丟去sum中較小的值start,而選一個比start大的值,即array[start++],直至start>=end爲止,如果start>=end還沒找到則說明滿足這種情況的例子不存在,輸出空,注意,可能存在多個滿足條件的例子,找到一個後然start+1或者end-1,然後繼續找下一個滿足條件的例子,直至start>=end爲止。
參考上面的例子的思路,因爲是找連續的正整數序列,因此我們可以這樣先定義一個start=1,end=2,然後類似滑動窗口的概念,我們通過讓增加start與end的值來動態的調整這個滑動窗口的範圍,直至這個滑動窗口中容納的正整數序列的和爲n,具體來說就是當滑動窗口中的和sum<n時則說明,我們應該讓這個滑動窗口容納更多的值,所以應該讓end+1,如果sum>n,則說明我們應該縮小這個滑動窗口容納的值,所以應該讓start+1,直至start<=n/2爲止,因爲至少得容納兩個數纔算序列。
基於上述思路,我們可以寫出如下的代碼:
#include <iostream>
using namespace std;
void printResult(int start,int end)
{
cout<<"[";
for(int i=start;i<=end;i++)
cout<<i<<",";
cout<<"]"<<endl;
}
void findSumIsN(int n)
{
int start=1,end=2;
int sum=start+end;;
while(start<(n+1)/2)
{
if(sum==n)
{
printResult(start,end);
}
while(sum<n)
{
end++;
sum+=end;
if(sum==n)
{
printResult(start,end);
}
}
sum-=start;
start++;
}
}
int main(int argc, char** argv) {
findSumIsN(15);
return 0;
}
程序輸出結果如下:
另外大家如果要訓練算法的話,給大家推薦一個網站leetcode,很不錯的,大家百度就可以搜到,另外如果大家刷leetcode上的題不是很懂,可以follow我的github賬號,本人在網上找到了一份很不錯的leetcode的解題報告,基本上AC過140道題,如果大家follow我的github賬號,本人後期將上傳該解題報告到github上供大家交流學習。我的github:https://github.com/HuTianQi,歡迎follow,star。