我尝试根据“算法导论”(第4章)一书实现这种最大子阵列算法。它可以运行,但结果不正确。我在这里找不到逻辑问题。谢谢。
def find_max_crossing_subarray(A,low,mid,high):
leftSum=float('-inf')
result=0 ## left_max_sum of midpoint
maxLeft=0
maxRight=0
for i in range(mid,low,-1):
result=result+A[i]
if result>leftSum:
leftSum=result
maxLeft=i
rightSum=float('-inf')
result2=0 ##right_max
for j in range(mid+1,high,1):
result2=result2+A[j]
if result2>rightSum:
rightSum=result2
maxRight=j
Result=result+result2
return maxLeft,maxRight,Result
def find_maximum_subarray(A,low,high):
if low==high:
return low, high, A[low]
else:
mid=(low+high)//2
leftLow,leftHigh,leftSum=find_maximum_subarray(A,low,mid)
rightLow,rightHigh,rightSum=find_maximum_subarray(A,mid+1,high)
crossLow, crossHigh,crossSum=find_max_crossing_subarray(A,low,mid,high)
if leftSum>=rightSum and leftSum>=crossSum:
return leftLow,leftHigh,leftSum
elif rightSum>=leftSum and rightSum>=crossSum:
return rightLow, rightHigh, rightSum
else:
return crossLow,crossHigh,crossSum
A=[1,2,30,21]
print (find_maximum_subarray(A,0,len(A)-1))
答案 0 :(得分:2)
发现它!
在find_max_crossing_subarray
,而不是range(mid,low,-1)
使用range(mid,low-1,-1)
而不是range(mid+1,high,1)
使用range(mid+1,high+1,1)
。
进一步解释:
来自range
documentation:
如果step为正,则最后一个元素是最大的start + i *步 少于停止;如果step为负数,则最后一个元素是最小的 开始+ i *步大于停止。
例如,range(0, 5)
表示[0, 1, 2, 3, 4]
。
另请参阅Ryan对Result
值的修正。
答案 1 :(得分:0)
当低和中等相同时,for循环不起作用。使用while而不是for是更好的选择。原始版本中的结果也不正确。
def find_max_crossing_subarray(A,low,mid,high):
leftSum=float('-inf')
result=0 ## left_max_sum of midpoint
maxLeft=0
maxRight=0
i=mid
while i>=low:
result+=A[i]
if result>leftSum:
leftSum=result
maxLeft=i
i-=1
rightSum=float('-inf')
result2=0
j=mid+1 ##right_max
while j<=high:
result2+=A[j]
if result2>rightSum:
rightSum=result2
maxRight=j
j+=1
Result=leftSum+rightSum
return maxLeft,maxRight,Result
答案 2 :(得分:0)
Kadane的算法包括扫描数组值,在每个位置计算在该位置结束的最大(正和)子阵列。此子阵列为空(在这种情况下,其总和为零)或由比在前一位置结束的最大子阵列多一个元素组成。算法只需要跟踪结束位置,因为隐含的起始位置恰好在最后一个位置之后,总和为负;通过删除任何负和前缀,总能找到更高的总和。
本质上,最简单的算法描述了一种解决方案,在该解决方案中,您必须循环遍历数组并找到当前值之前可能存在的最大子数组。
为简化该算法,您可以消除任何负数,并将您的起始索引保留在前一个总和为正的位置。您可以这样做,因为任何数组的空数组的最小总和为。
因此,您可以简化算法:
def mssl(l):
best = cur = 0
for i in l:
cur = max(cur + i, 0)
best = max(best, cur)
return best
致谢至Wikipedia进行解释。
发现here的同类问题,用户nneonneo
给出了很好的答案