首先來看題目描述:
給定一陣列a[n],我們希望構造陣列b [n],其中b[j]=a[0]*a[1]…a[n-1] / a[j],在構造過程中,不允許使用除法:
要求o(1)空間複雜度和o(n)的時間複雜度;
除遍歷計數器與a[n] b[n]外,不可使用新的變數(包括棧臨時變數、堆空間和全域性靜態變數等);
實現程式(主流程式語言任選)實現並簡單描述。
這道題目最為獨特的要求就是除去遍歷計算器外不能申請其它新的變數。怎麼解決了?首先不考慮這個條件,**如下:
////by morewindows( )
#include
void printfarray(int a, int n)
int main()
; int b[maxn];
printf("陣列a為:\n");
printfarray(a, maxn);
b[0] = 1;
int i;
for (i = 1; i < maxn; i++)
b[i] = b[i - 1] * a[i - 1];
int temp = 1;
for (i = maxn - 2; i >= 0; i--)
printf("陣列b為:\n");
printfarray(b, maxn);
return0;}
解釋下**,設有陣列大小為5。
對於第乙個for迴圈
第一步:b[0] = 1;
第二步:b[1] = b[0] * a[0] = a[0]
第三步:b[2] = b[1] * a[1] = a[0] * a[1];
第四步:b[3] = b[2] * a[2] = a[0] * a[1] * a[2];
第五步:b[4] = b[3] * a[3] = a[0] * a[1] * a[2] * a[3];
然後對於第二個for迴圈
第一步
temp *= a[4] = a[4];
b[3] = b[3] * temp = a[0] * a[1] * a[2] * a[4];
第二步
temp *= a[3] = a[4] * a[3];
b[2] = b[2] * temp = a[0] * a[1] * a[4] * a[3];
第三步
temp *= a[2] = a[4] * a[3] * a[2];
b[1] = b[1] * temp = a[0] * a[4] * a[3] * a[2];
第四步
temp *= a[1] = a[4] * a[3] * a[2] * a[1];
b[0] = b[0] * temp = a[4] * a[3] * a[2] * a[1];
由此可以看出從b[4]到b[0]均已經得到正確計算。
執行結果如下所示:
然後考慮到題目要求不能申請額外的臨時變數,因此int temp肯定是不能有的,那用什麼來代替這個temp了?很簡單,用b[0]來代替即可。於是上面的第二個for迴圈語句變為:
for (i = maxn - 1; i >= 1; i--)
試驗下,執行結果如下所示:
呵呵,b[0]一代替,輕輕鬆鬆加分到手^_^。
白話經典演算法系列
堆排序與快速排序,歸併排序一樣都是時間複雜度為o n logn 的幾種常見排序方法。學習堆排序前,先講解下什麼是資料結構中的二叉堆。二叉堆的定義二叉堆是完全二叉樹或者是近似完全二叉樹。二叉堆滿足二個特性 1 父結點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值。2 每個結點的左子樹和右子樹都...
白話經典演算法系列之八 白話經典演算法之七大排序總結篇
在我的部落格對氣泡排序,直接插入排序,直接選擇排序,希爾排序,歸併排序,快速排序和堆排序這七種常用的排序方法進行了詳細的講解。首先回顧下各種排序的主要思路 一 氣泡排序 氣泡排序主要思路是 通過交換使相鄰的兩個數變成小數在前大數在後,這樣每次遍歷後,最大的數就 沉 到最後面了。重複n次即可以使陣列有...
白話經典演算法系列之 快速排序 快速搞定
總的說來,要直接默寫出快速排序還是有一定難度的,因為本人就自己的理解對快速排序作了下白話解釋,希望對大家理解有幫助,達到快速排序,快速搞定。快速排序是c.r.a.hoare於1962年提出的一種劃分交換排序。它採用了一種分治的策略,通常稱其為分治法 divide and conquermethod ...