递归最大子数组未返回正确值
Posted
技术标签:
【中文标题】递归最大子数组未返回正确值【英文标题】:Recursive Maximum Subarray not returning correct value 【发布时间】:2021-06-03 11:40:51 【问题描述】:我正在尝试解决这个问题,给我一个数组,我应该找到最大的差异,即较大的数字在较小的数字之后。例如,如果我有数组:
[100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 101, 79, 94, 90, 97]
那么输出应该是(7, 11, 43)
,其中7
是起始索引(值63),11
是结束索引(值106),43
是差值/利润。
但是,我得到的输出是(0, 16, 1607)
。
有几个类似问题的线程,但不幸的是我需要非常密切地关注下面的伪代码,所以我找不到有用的东西。
这是我到目前为止的代码。不太确定为什么它给了我错误的输出。请注意,伪代码是基于 1 个索引的,即它从索引 1 而不是 0 开始。
def find_max_crossing_subarray(A, low, mid, high):
max_left = low
max_right = high
left_sum = -math.inf
sum = 0
for i in reversed(range(low, mid)):
sum = sum + A[i]
if sum > left_sum:
left_sum = sum
max_left = i
right_sum = -math.inf
sum = 0
for j in range(mid, high):
sum = sum + A[j]
if sum > right_sum:
right_sum = sum
max_right = j
return (max_left, max_right, left_sum + right_sum)
def find_maximum_subarray(A, low, high):
if low + 1 == high:
return (low, high, A[low])
else:
mid = (low + high) // 2
(left_low, left_high, left_sum) = find_maximum_subarray(A, low, mid)
(right_low, right_high, right_sum) = find_maximum_subarray(A, mid, high)
(cross_low, cross_high, cross_sum) = find_max_crossing_subarray(A, low, mid, high)
if left_sum >= right_sum and left_sum >= cross_sum:
return (left_low, left_high, left_sum)
elif right_sum >= left_sum and right_sum >= cross_sum:
return (right_low, right_high, right_sum)
else:
return (cross_low, cross_high, cross_sum)
bf = find_maximum_subarray(array, 0, len(array))
print(bf)
【问题讨论】:
看起来只是返回整个数组的总和 值 106 在索引 11 处。 你贴的伪代码是针对最大子数组和问题的,与问题中的问题完全无关。 您发送的数组长度为高。这没有任何意义。 @user3386109 抱歉,我修好了。这是我提供的伪代码,所以我不确定。我也添加了问题描述。 【参考方案1】:这样做不是更容易吗?
def min_max_diff(x):
def process(x):
y = sorted(x)
min = y[0]
max = sorted(x[x.index(min):])[-1]
return min, max
while x:
min, max = process(x)
if max <= min:
x.remove(min)
min, max = process(x)
else:
break
return min, max, max-min
x = [100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 101, 79, 94, 90, 97]
result = min_max_diff(x)
print(result)
【讨论】:
如果数组的最小元素是数组的最后一个元素,则肯定不起作用。 如果元素按从大到小的顺序排列,则没有任何效果 示例:[2,3,1] 已更新以支持此条件 @eatmeimadanish 也许,但如前所述,我必须尽可能地遵循伪代码。是的,我知道这很糟糕..【参考方案2】:这个问题可以通过对给定数组进行一次遍历来解决,并且您不需要为这个问题计算最大子数组。可能问题陈述和最大子数组是两个不同的问题。
明确提到,您只能购买一只股票并在以后出售。所以,直觉是:
我们总是尽量降低购买价格 对于每一个可能的购买价格,我们都会尝试通过以更高的未来价格出售来最大化利润。下面的 C++ 代码解决了这个问题:
int maxProfit(vector<int>& prices)
int sz = prices.size();
if(sz < 2) return 0;
int mxProfit = -INT_MAX, minPrice = prices[0];
for(int i=0; i<sz; i+=1)
mxProfit = max(mxProfit, prices[i] - minPrice);
minPrice = min(minPrice, prices[i]);
return mxProfit;
【讨论】:
以上是关于递归最大子数组未返回正确值的主要内容,如果未能解决你的问题,请参考以下文章