子陣列換位問題
設a[0:n-1]是乙個有n個元素的陣列,k(0<=k<=n-1)是乙個非負整數。 試設計乙個演算法將子陣列a[0:k]與a[k+1,n-1]換位。要求演算法在最壞情況下耗時o(n),且只用到o(1)的輔助空間(來自《計算機演算法設計與分析》- 王曉東 - 第三章 - 遞迴與分治策略 - 課後習題)
初步思考:最簡單的方法就是迴圈(n-k-1)次,將a陣列的末尾數字插入到a[0]之前。
具體做法:(1) 首先開闢乙個額外空間temp用於存放每一次a陣列的末尾資料。
(2) temp <- a[n-1]
(3) 將a[0: n-2] 每個資料都依次向後移動一位賦值給a[1: n-1]。
(4) a[0] <- temp
(5) 迴圈執行(2) -(4) 步 (n-k+1)次。
代價分析: 時間代價—— o((n-1)*(n-k+1)) 即o(n^2)數量級;空間代價——o(1)
我們仔細想想還有沒有更快的辦法呢?試想一下,如果a[0 : k] 與
a[k+1 : n-1] 正好長度相等,則可以直接一一對應交換即可。 當然,這道題的難點就在於k並不一定是a陣列的中間位置。即便如此,但是仍然可以交換:
如果a[0 : k].length< a[k+1 : n-1].length, 則可以將a[0 : k] 與 a[k+1 : n-1] 中最後一部分大小相同的資料交換:
|-------- a[k+1 : n-1] -----------|
a[0:k]
a[k+1 : n-k-2] a[n-k-1 : n-1]
其中 a[0:k] 與 a[n-k-1 : n-1] 長度相同,因此完全可以一一對應交換成:
|------ a[0 : n-k-2] -------|
a[0:k]
a[k+1 : n-k-2]
a[n-k-1 : n-1]
交換完成以後,則a[n-k-1 : n-1] 已經交換到位,而a[0 :
n-k-2
]還需要進一步這樣遞迴交換。
源**如下:
#include//交換陣列的兩段大小相等的範圍的對應資料
//a[low1] <->a[low2] a[low1+1]<->a[low2+1] ... a[high1] <-> a[high2]
void swap(int a,int low1,int high1,int low2,int high2)
}//利用分治演算法, 每次選擇最小的陣列進行換位
void patition(int a, int low, int k, int high){
if(low這樣的時間複雜度為o(n),而且交換資料的時候只需要o(1)的額外空間。
再談子陣列 子串問題
這類問題都是求乙個滿足某種條件的連續的段,相對於子串行。字串和陣列的主要區別是,前者因為由字元而不是數值組成,一般不會有最大值,最小值,求和這種問題。對於字串的子串問題,一般條件是子串符合某種pattern 回文 有序 或者滿足某種統計特徵 子串內無重複字元,最多重複2次,包含了給定字符集的所有字元...
子陣列最大和問題
1.最大子序和 給定乙個整數陣列 nums 找到乙個具有最大和的連續子陣列 子陣列最少包含乙個元素 返回其最大和。示例 輸入 2,1,3,4,1,2,1,5,4 輸出 6 解釋 連續子陣列 4,1,2,1 的和最大,為 6。class solution else ans ans sum?ans su...
子陣列之和最大 貪婪演算法
求子陣列的最大和 題目 輸入乙個整形陣列,陣列裡有正數也有負數。說明子陣列之最大和一定大於0 陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。求所有子陣列的和的最大值。要求時間複雜度為o n 例如輸入的陣列為1,2,3,10,4,7,2,5,和最大的子陣列為3,10,4,7,2,因此...