騰訊一道面試題

來源:互聯網
上載者:User

28)給定一數組a[N],我們希望構造數組b [N],其中b[j]=a[0]*a[1]…a[N-1] / a[j],在構造過程中,不允許使用除法:

要求O(1)空間複雜度和O(n)的時間複雜度;

除遍曆計數器與a[N] b[N]外,不可使用新的變數(包括棧臨時變數、堆空間和全域靜態變數等);

實現程式(主流程式設計語言任選)實現並簡單描述。

先忽略題目所給的任何限制,天馬行空想象一下,能想象到什麼解法?

1.最簡單的辦法,將a[0]到a[N-1]全乘起來,再遍曆數組,依次除以a[j]即可,這是最簡單的辦法,但是,不允許使用除法,此法不可行.

2.既然不能使用除法,我們可以換一種思維方式:先將a[j]左邊的數全乘一遍,a[j]右邊的數全乘一遍,二者再乘起來,就可以避免除法,得到了a[j]的值.這樣子,顯然要求得每一個a[i]都需要遍曆一遍數組,時間複雜度為o(n),求完所有的a[0]到a[N-1],時間複雜度為o(n^2).不符合題意.但是,這個辦法給我們提供了一種可能性,那就是,能不能在二層嵌套迴圈中整合成一層嵌套迴圈?這個問題暫時不得而知,但是,我們可以知道的是,我們可以實現這個o(n^2)的方法,先實現出來再看看接下來能不能降低時間複雜性.

o(n^2)時間複度性的代碼:

void ConstructArray(int* A,int* B,int N){for(int i=0;i<N;++i){B[i]=1;for(int j=0;j<N;++j){if(j != i){B[i]=B[i]*A[j];}}}}

即: | 為分割線.

表:1-1

A[0]=1|*A[1]*A[2]*........*A[N-1]

A[1]=A[0]*|*A[2]*A[3].......A[N-1]

A[2]=A[0]*A[1]*|*A[3]*......A[N-1]

......

A[j]=A[0*A[1]*...A[j-1]|A[j+1]*A[j+2]*...A[N-1]

上面的代碼實現思路是這樣子的:將問題分為兩部分:對於A[0],A[1].....到A[N-1]的每一個A[i],通過一遍的迴圈遍曆數組得出結果.這樣子就形

成二層嵌套.

現在,我們需要換一個角度想,能不能將分割線|左右兩邊的結果全算出來儲存在一個數組中,然後,兩個數組對應相乘就可以解決問題了.中間,我們不需要兩個暫時數組,可以利用B[N]數組的特點來完成這種累積的過程.

void ConstructArray(int* A,int* B,int N){if(!A || !B) return ;B[0]=1;for(int i=0;i<=N-2;++i){B[i+1]=B[i]*A[i];//對比表:1-1容易知道,構造分割線左邊部分}//上面已經建立了一個金字塔式的左分割線部分,現在自底向上重複上面的操作就能建立右分割線部分for(int i=N-1;i>=1;--i){B[i]=B[i]*B[0];B[0]=B[0]*A[i];}}

總結:

1題目要求比較苛刻,思維方式是利用B[i]構造左邊金字塔型的數組,再構造右邊的金字塔型.中間的轉換比較巧妙.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.