面試題之子串行分析

2021-06-18 07:21:02 字數 1414 閱讀 7740

原題

給定長度為n的整數數列:a0,a1,..,an-1,以及整數s。這個數列會有連續的子串行的整數總和大於s的,求這些數列中,最小的長度。

分析如果只是像題目這樣的描述,沒有強調正數,可以採用o(n^2)的方法。---------

-解法一

但是,很多同學在討論的時候,指出了如果是正數,解法將會有什麼樣的變化。這個很好。不考慮正負的o(n^2)的方法,這裡不詳細說了,我們來討論,當數列中都是正數的情況。

介紹乙個利用排序+二分的方法。對於子串行ai...at,子串行和s=ai+...+at=sum[t]-sum[i-1]。sum[t]表示數列a0...at的和。那麼,陣列sum天然就是遞增的,可以進行二分查詢。 那麼如何進行二分查詢呢?對於陣列sum,遍歷找到第乙個k,sum[k]>s,二分查詢k前面的某乙個j,j是sum[k]-sum[j]>s裡最大的乙個,則k-j是最小的。依次遍歷完陣列。 可以得到最小的長度,整體的時間複雜度o(nlogn),空間複雜度為o(n)。------

解法二

是否有更快的方法呢?從以上兩個方法,我們可以有如下的觀察:---------解法三

鑑於以上的觀察,我們有如下的演算法:設定索引i,j指向第乙個整數:

++j,直到sum[j]-sum[i]>s,這裡不需要額外儲存sum,為了方便說明。記錄子串行長度

++i,如果sum[j]-sum[i]>s,更新最小子序列長度。直到sum[j]-sum[i]<=s。

++j,直到sum[j]-sum[i]>s。重複上面的兩步,直到陣列遍歷完畢。

整個演算法的時間複雜度為o(n)。下面我們做乙個示例陣列為,s=10,i=j=0開始

當j=3時,和為14>10,則更新最小長度為4

對i進行遞增操作,和為9<10,不滿足條件。對j進行遞增

當i=1,j=4時,和為19>10,長度為4,不更新最小長度。遞增i,直到i=3,此時和15>10,更新最小長度為2,

依次類推

最終得到最小長度為2.

【分析完畢】

附:解法一**:

#include #include int main()

else

else if (tmp_count < count)

break;

}} }

printf("number is:%d\n", count);

return 0;

}

解法二:

#include #include int main()

for (i = 0; i < n; i++)

}} }

printf("%d\n", count);

return 0;

}

解法三:

Promise 序列呼叫面試題

最新看到乙個比較有趣的面試題 怎麼序列執行 promise 這裡簡單給大家介紹下解答。針對多個 promise 方法,原生提供了all和race方法。但是,他們都不是序列執行。那應該如果執行序列方法?這裡介紹兩種寫法 遞迴執行 function iteratorpromise arr let arr...

面試題 PHP面試題

建議 比如是系統配置,缺少了無法執行,自然使用 require 如果某一段程式少了,只是少了統計 訪問的,不是必不可少的。可以使用 include 而加不加 once 就是效率上的區別,雖然系統會幫你考慮只包含一次,但系統的判斷會降低效率,因此,更應該在開發之初,把目錄結構調整高好,盡量不使用 on...

海量資料面試題分析

轉知乎,手敲一遍,加深記憶 箴言 無論是這些海量資料處理面試題也好,還是演算法也好,面試時,70 80 的人不是倒在這兩方面,而是倒在基礎之上 諸如語言,資料庫,作業系統,網路協議等等 所以,無論任何時候,基礎最重要,沒了基礎,便什麼都不是。何謂海量資料處理?無非就是基於海量資料上的儲存,處理,操作...