給定一個整數數組,如何找到兩個索引i和j,以使子索引中的索引開始和結束的元素總和最大化,線性爲時間?以int爲單位的最大總和的子序列
回答
從我的programming pearls副本:
maxsofar = 0
maxendinghere = 0
for i = [0, n)
/* invariant: maxendinghere and maxsofar are accurate
are accurate for x[0..i-1] */
maxendinghere = max(maxendinghere + x[i], 0)
maxsofar = max(maxsofar, maxendinghere)
一個正確和簡潔的。但它花了你同時把它複製下來,因爲我設計它:) – 2009-11-10 09:39:59
Soooo,那麼'我'和'j'是什麼? – 2009-11-10 12:33:43
要獲得序列的開始和結束,您只需要記住正確的i(ndex到數組中),具體取決於您在兩個max語句中選擇的內容。 – 2009-11-10 13:41:47
很簡單。假設你得到了數組a
。首先,你計算陣列s
,其中s[i] = a[0]+a[1]+...+a[i]
。你可以做到這在線性時間:現在
s[0]=a[0];
for (i=1;i<N;i++) s[i]=s[i-1]+a[i];
,總和a[i]+a[i+1]+..+a[j]
等於s[j]-s[i-1]
。對於固定的j
,要最大化這種差異的值,您應該在0..(j-1)
範圍內找到最小的。
想象一下在數組中尋找最小值的常用算法。
min = x[0];
for (j=1; j<N; j++)
if (x[j] < min)
min = x[j];
您迭代,每個數組元素比較min
...但在每次迭代這min
是數組,其中索引範圍是0..j
最低值!這就是我們正在尋找的!
global_max = a[0];
max_i = max_j = 0;
local_min_index = 0;
for (j=1; j<N; j++){
// here local_min is the lowest value of s[i], where 0<=i<j
if (s[j] - s[local_min_index] > global_max) {
global_max = s[j] - s[local_min_index]
//update indices
max_i = local_min_index + 1;
max_j = j;
}
//update local_min_index for next iteration
if (s[j]<local_min){
local_min = s[j];
// update indices
local_min_index = j;
}
}
感謝匿名用戶爲他的冗長帖子解釋代碼中的錯誤。我擺脫了它們,除了如果'N == 0'失敗。 – 2013-03-29 22:46:28
這個Python代碼返回序列的邊界。根據原來的問題,i=bestlo
,j=besthi-1
。
#
# given a sequence X of signed integers,
# find a contiguous subsequence that has maximal sum.
# return the lo and hi indices that bound the subsequence.
# the subsequence is X[lo:hi] (exclusive of hi).
#
def max_subseq(X):
#
# initialize vars to establish invariants.
# 1: best subseq so far is [bestlo..besthi), and bestsum is its sum
# 2: cur subseq is [curlo..curhi), and cursum is its sum
#
bestlo,besthi,bestsum = 0,0,0
curlo,curhi,cursum = 0,0,0
for i in xrange(len(X)):
# extend current subseq and update vars
curhi = i+1
cursum += X[i]
if cursum <= 0:
#
# the current subseq went under water,
# so it can't be usefully extended.
# start fresh at next index.
#
curlo = curhi
cursum = 0
elif cursum > bestsum:
# adopt current subseq as the new best
bestlo,besthi,bestsum = curlo,curhi,cursum
return (bestlo,besthi)
下面是這段代碼通過的一些doctest示例。
r'''
doctest examples:
>>> print max_subseq([])
(0, 0)
>>> print max_subseq([10])
(0, 1)
>>> print max_subseq([-1])
(0, 0)
>>> print max_subseq(xrange(5))
(1, 5)
>>> print max_subseq([-1, 1, -1])
(1, 2)
>>> print max_subseq([-1, -1, 1, 1, -1, -1, 1, 2, -1])
(6, 8)
>>> print max_subseq([-2, 11, -4, 13, -5, -2])
(1, 4)
>>> print max_subseq([4, -3, 5, -2, -1, 2, 6,-4])
(0, 7)
'''
你真正需要Kadane的算法變更該記住的下限和上限爲子陣列,這裏的C++代碼11:
#include <iostream>
#include <vector>
typedef std::pair<std::vector<int>::iterator, std::vector<int>::iterator> SubSeq;
SubSeq getMaxSubSeq(std::vector<int> &arr) {
SubSeq maxSequence{arr.begin(), arr.begin()};
auto tmpBegin = arr.begin();
int maxEndingHere = 0;
int maxSoFar = 0;
for(auto it = arr.begin(); it < arr.end(); ++it) {
int currentSum = maxEndingHere + *it;
if(currentSum > 0) {
if(maxEndingHere == 0) {
tmpBegin = it;
}
maxEndingHere = currentSum;
} else {
maxEndingHere = 0;
}
if(maxEndingHere > maxSoFar) {
maxSoFar = maxEndingHere;
maxSequence.first = tmpBegin;
maxSequence.second = it + 1;
}
}
return maxSequence;
}
int main()
{
std::vector<int> arr{-1, 2, 90, -50, 150, -300, 56, 12};
auto seq = getMaxSubSeq(arr);
while(seq.first != seq.second) {
std::cout << *(seq.first) << " ";
++(seq.first);
}
return 0;
}
- 1. 最大總和子列表?
- 2. 返回最大子列表的總和
- 3. 排序列表中的最大總和
- 4. x元素的最大連續子序列總和
- 5. 最大的二維子集和總和
- 6. 子陣最大總和
- 7. 最大和最小的INT
- 8. 查找最大總和子列表和總結分而治之
- 9. 確定最大總和的行和列
- 10. 查找2D numpy的陣列最大總和的位置
- 11. Hive中列的總和的最大值
- 12. 最小/最大 「總和」 的
- 13. 以毫秒爲單位的序列號
- 14. 除以列中的值的總和的最大值排
- 15. 長度和最長增加的子序列的總和
- 16. 查找最大連續子序列總和的開始和結尾
- 17. 選擇兩列總和的最大值
- 18. 以2d列表和編寫程序爲列最大和平均
- 19. 最大的連片子陣的總和大小不大於k
- 20. 連續子序列的最大和爲零?
- 21. 作爲int [](Java)int [] []行的總和
- 22. 找到所有子陣列中最大值的總和
- 23. 非重疊連續子陣列的最大長度總和
- 24. 獲取文件的總大小以字節爲單位
- 25. 以字節爲單位確定緩衝區的總大小
- 26. 找到最大的最大總和,兼容,在子二次時間兩個已排序的陣列的值
- 27. 序言 - 找到一個二叉樹的最大總和子樹
- 28. 以KB/MB爲單位的大小,僅最大。逗號後的2位數
- 29. Haskell的性能時最小/最大/總和在大列表
- 30. 最大和最小總和
你的意思是 - 指數之間? – Vladimir 2009-11-10 09:06:21
'i = 0'和'j = array.length-1' :) – 2009-11-10 09:08:25
@Bart,誰說數組元素大於零? – 2009-11-10 09:09:28