子序列;及又見排序分析

紫鳳發表於2013-09-16

今日面試題:子序列

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

============================================

又見排序分析

原題

給定大小為n的陣列A,A中的元素有正有負。請給出方法,對其排序,保證:

負數在前面,正數在後面

正數之間相對位置不變

負數之間相對位置不變

能夠做到時間複雜度為O(n),空間複雜度為O(1)麼?

分析

這類題目,還有其他的變形,比如,陣列A有奇數和偶數,排序奇數在前偶數在後,並且奇數和偶數內部的相對順序不能變。那麼這類的題目,該如何解決呢?

首先,暴力法可行:從左到右掃描陣列,遇到第一個負數,與其前面的每一個元素進行交換,直到第一個位置,這裡並不能直接交換, 因為這樣就改變了正數的相對位置了。後面的繼續掃描,第二個負數,依次交換到第二個位置。依次類推。演算法總的時間複雜度為O(n^2)。

上面這個方法,大多數同學,都可以給出。那麼,是否有更快的方法呢?大家請看下面的方法:

統計負數的個數,設為M

找到索引k>M的第一個負數

使用i和j兩個索引,i從0開始,直到遇到第一個正數,j從k開始,直到遇到第一個負數。交換i,j位置上的數,然後符號取反

對於A[0,M]和A[M, n]分別執行上面三步

修正符號:前面的M個為負數,後面的為正數。

下面舉例來說明,對於陣列{-1,1,3,-2,2},根據描述,有M=2,k=3。i遇到第一個正數為A1=1,j遇到第一個負數為A[3]=-2。然後交換i和j位置上的值, 陣列變為{-1, -2, 3, 1, 2}, 然後改變符號,得到{-1,2,3,-1,2}。然後遞迴處理{-1,2},{3,-1,2},最終得到{-1,2,1,-3,2}。進行最後一步,修正符號, 得到{-1,-2,1,3,2}。即為最終答案。這個方法是nlog(n)的,比上面的提高了一些。

但是上面的方法,仍舊不是O(n)的。那麼O(n)的方法,是否存在呢?我們認為,接近O(n)的方法是有的。但是,方法過於複雜。這類問題,可以統稱為 stable 0-1 sorting。還是蠻有意思的。大家感興趣的話,可以參考下面的文章:

http://www.diku.dk/hjemmesider/ansatte/jyrki/Paper/KP92b.pdf

【分析完畢】

本文來自微信:待字閨中,2013-09-04釋出,原創@陳利人 ,歡迎大家繼續關注微信公眾賬號“待字閨中”。

相關文章