python - 为什么我的“最大连续子数组和”解决方案不适用于所有输入?
问题描述
对于上下文,这是 Codewars 中的问题陈述: 问题陈述
它本质上是经典的“查找最大子数组和”问题,尽管重要的附加细节是在给定所有负数的数组的情况下应该返回“0”,而不仅仅是最大的负数。
首先,我完全意识到这个解决方案不是一个非常好的或有效的解决方案。话虽如此,对我来说逻辑仍然有意义,所以我不太明白为什么它适用于某些输入而不适用于其他输入。由于测试用例隐藏在 Codewars 中,我无法提供该程序无效的输入。
我尝试使用以下示例运行代码;
- [1, 0, 2, -3, 6] (应该返回 6)
- [-2, 1, -3, 4, -1, 2, 1, -5, 4] (应该返回 6)
- [-2, -3, 4, -1, 5, 1, 5, -3](应该返回 14)
- 等等,他们都工作得很好
同样,我只想知道为什么这段代码不正确背后的逻辑。我不是在寻找正确的替代解决方案(我现在已经知道 Kadane 算法的存在)。这是我第一次盲目尝试解决这个问题,所以我真的很想知道我做错了什么,以便从中吸取教训。
def max_sequence(arr):
max_sum = 0
max_subarr_index = 0
for i, val in enumerate(arr):
max_sum = max(max_sum, sum(arr[max_subarr_index:i+1]), val)
if max_sum == val:
max_subarr_index = i
return max_sum
解决方案
缺陷在于max_sum
您的算法具有双重用途。它用于:
在迄今为止探索的数组上保持最大找到的总和
max_subarr_index
如果较大的数组直接从索引开始i
而不是更新max_subarr_index
对于第一点,您的算法工作得很好。第二次它失败了,因为max_sum
与您当前正在查看的子数组没有任何关系。例如:
arr = [3, -4, 1, 1, ...]
现在i = 3
变量看起来像这样:
max_sum = 3
max_subarr_index = 0
即算法仍然“认为”最大子数组从索引 0 开始并且总和为 3。但是以索引 3 结束的最大子数组实际上[1, 1]
是max_subarr_index = 2
. 即实际上有两个最大子数组:
- 全局的(
[3]
fori = 3
) - 以当前索引结束的最大和子数组(
[1, 1]
fori = 3
)
max_subarr_index
您可以通过仅根据val
和的最大值进行更新来解决此问题sum(arr[max_subarr_index:i+1])
:
def max_sequence(arr):
max_sum = 0
max_subarr_index = 0
for i, val in enumerate(arr):
# update max_subarr_index based on sum of "current" max subarray
tmp = max(sum(arr[max_subarr_index:i+1]), val)
if tmp == val:
max_subarr_index = i
# global maximum found so far
max_sum = max(max_sum, tmp)
return max_sum
推荐阅读
- sql - 如果不存在,则在表中插入新行
- r - 从命令行运行 Rscript 时如何转义空格?
- python - Python3.7.1:`10**3.5`:无法将字符串转换为浮点数:3.5
- c# - 调试时忽略某个位置的异常?
- arrays - java.sql.SQLException:通过jdbcTemplate的参数索引超出范围(1>参数个数,即0)
- php - 将数组键传递给变量
- click - 使鼠标单击整个区域而不是点
- amazon-web-services - 如何使用 IAM ROLE 将数据从 S3 发送到 vertica?
- jquery - 将编辑器模板逐行添加到 Html 表并发送到控制器
- c# - 使用 WPF/MVVM,如何在关闭外部进程后立即将焦点恢复到我的应用程序?