程式設計珠璣第八章,最接近0的的子向量
阿新 • • 發佈:2019-01-27
看了程式設計珠璣第八章中的內容,後面的課後練習也是非常的有意思,有一題是這麼說的,給定整數m和整數n和實數向量x[n],
請找出使總和x[i]+……+x[i+m]最接近0的整數i。
我這裡先不說明怎麼獲取最接近0的i,我先說明如何獲得與0最接近的子陣列之和。
看了寫網上有些人已經多出了一些解法,但是覺得它們的做法好像都有些問題。例如這位大神的做法就是有些問題的。
int approximate(int * pArry, int len) { int * cum = 0; int * realarry = new int[len + 1]; realarry[0] = 0; cum = realarry + 1; //cum[-1] = 0 //累計pArry[0....i]的和存放於cum[i]中 for (int i = 0; i < len; i++) { cum[i] = cum[i - 1] + pArry[i]; } sort(cum, cum + len); //對cum排序 int iMin = cum[1] - cum[0]; for (int k = 1; k < len; k++) { iMin = min(iMin, cum[k] - cum[k - 1]); //返回相鄰兩個元素差值最小的 } return iMin; }
式子中的cum[i]代表的是從第一個元素到該元素的累加和,如果cum[l-1] = cum[n],那麼cum[l..n]就是最接近0子向量,這裡一定是0.但是,最接近0的子向量也很差不多,只要把所有的cum排序就是了,delta最小的就是了,整個演算法複雜度就是排序了。他的程式碼中沒有考慮cum[i] 直接為0的情況,顯然這時候的意思是從陣列的開始到該元素的累加和就是0。
他的程式碼對於這個example是會出錯的[-1,-1,2,1,2]
其實只需要新增一行程式碼就可以了。
int approximate(int * pArry, int len) { int * cum = 0; int * realarry = new int[len + 1]; realarry[0] = 0; cum = realarry + 1; //cum[-1] = 0 //累計pArry[0....i]的和存放於cum[i]中 for (int i = 0; i < len; i++) { cum[i] = cum[i - 1] + pArry[i]; if(cum[i]==0) return 0; } sort(cum, cum + len); //對cum排序 int iMin = cum[1] - cum[0]; for (int k = 1; k < len; k++) { iMin = min(iMin, cum[k] - cum[k - 1]); //返回相鄰兩個元素差值最小的 } return iMin; }