1. 程式人生 > >【BAT經典演算法面試題系列】求和為n的連續正整數

【BAT經典演算法面試題系列】求和為n的連續正整數

馬上就要到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;
}
整個程式碼基本上就是上述思路轉化為程式語言之後的結果,程式碼很簡單,所以也沒加啥註釋,雖然很簡單,但是卻能夠考察一個程式設計師能否將自己的思考過程用程式化的語言表達出來,這也是BAT重視演算法面試的原因所在。

程式輸出結果如下:

另外大家如果要訓練演算法的話,給大家推薦一個網站leetcode,很不錯的,大家百度就可以搜到,另外如果大家刷leetcode上的題不是很懂,可以follow我的github賬號,本人在網上找到了一份很不錯的leetcode的解題報告,基本上AC過140道題,如果大家follow我的github賬號,本人後期將上傳該解題報告到github上供大家交流學習。