MaxDoubleSliceSum 算法

Posted

技术标签:

【中文标题】MaxDoubleSliceSum 算法【英文标题】:MaxDoubleSliceSum Algorithm 【发布时间】:2015-04-14 21:04:28 【问题描述】:

我正在尝试解决查找 MaxDoubleSliceSum 值的问题。简单地说,它是任何切片减去该切片中的一个元素的最大总和(您必须删除一个元素,并且第一个和最后一个元素也被排除在外)。因此,从技术上讲,数组的第一个和最后一个元素不能包含在任何切片和中。

这是完整的描述:

给出了一个由N 整数组成的非空零索引数组A。 三元组(X, Y, Z),如0 ≤ X < Y < Z < N,称为双切片。 双切片(X, Y, Z)的总和就是A[X + 1] + A[X + 2] + ... + A[Y − 1] + A[Y + 1] + A[Y + 2] + ... + A[Z − 1]的总和。

例如,数组A 这样:

A[0] = 3
A[1] = 2
A[2] = 6
A[3] = -1
A[4] = 4
A[5] = 5
A[6] = -1
A[7] = 2

包含以下示例双切片:

双切片(0, 3, 6),总和为2 + 6 + 4 + 5 = 17

双切片(0, 3, 7),总和为2 + 6 + 4 + 5 − 1 = 16

双切片(3, 4, 5),总和为0

目标是找到任何双切片的最大和。

写一个函数:

def solution(A) 即,给定一个由 N 整数组成的非空零索引数组 A,返回任何双切片的最大和。

例如,给定:

A[0] = 3
A[1] = 2
A[2] = 6
A[3] = -1
A[4] = 4
A[5] = 5
A[6] = -1
A[7] = 2

该函数应返回17,因为数组A 的双切片的总和不大于17

假设:

N 是 [3..100,000] 范围内的整数;

数组A的每个元素都是[−10,000..10,000]范围内的整数。

复杂性:

预计最坏情况时间复杂度为O(N)

预计最坏情况下的空间复杂度为O(N),超出输入存储(不包括输入参数所需的存储)。

输入数组的元素可以修改。

这是我的尝试:

def solution(A):
    if len(A) <= 3:
        return 0
    max_slice = 0
    minimum = A[1]    # assume the first element is the minimum
    max_end = -A[1]   # and drop it from the slice
    for i in xrange(1, len(A)-1):
        if A[i] < minimum:        # a new minimum found
            max_end += minimum    # put back the false minimum
            minimum = A[i]        # assign the new minimum to minimum
            max_end -= minimum    # drop the new minimum out of the slice
        max_end = max(0, max_end + A[i])
        max_slice = max(max_slice, max_end)
    return max_slice

让我认为这可能接近正确的解决方案但问题的某些角落可能尚未涵盖的原因是 14 个测试用例中有 9 个正确通过 (https://codility.com/demo/results/demoAW7WPN-PCV/) 我知道这可以通过向前和向后应用 Kadane 算法来解决。但如果有人能指出这里缺少什么,我将不胜感激。

【问题讨论】:

它告诉你测试是什么;您为什么不尝试复制测试并查看输出以获取最小的失败示例?您可以针对蛮力算法进行测试以获得可靠的答案。 这个问题在相同的上下文中解决了相同的问题(不同的语言,但想法是存在的):***.com/questions/20660989/max-double-slice-sum 发现错误,尝试[-20, -10, 10, -70, 20, 30, -30]。应该是 60 而不是 50 【参考方案1】:

这就是我编写算法的方式。

假设起始索引为 X=0,然后对右侧的平方进行迭代求和。

在计数时跟踪最低 int 的索引,并在使用时从总和中减去最低 int。这可以有效地让您放置 Y。 跟踪最大总和以及该总和的 X、Y、Z 值 如果总和变为负数,则将最大总和保存为结果,只要它大于之前的结果。 选择一个新的 X,你应该开始关注 Y 并从你找到的任何索引中减去一个。并重复前面的步骤,直到到达列表的末尾。

这可能是一种改进吗? 您的代码的潜在问题案例:[7, 2, 4, -18, -14, 20, 22] -18 和 -14 将数组分成两段。第一段的总和是 7+2+4=13,第二段的总和只有 20。上面的算法处理这种情况,你的可能,但我不擅长 python(对不起)。

编辑(错误和解决方案):看来我的原始答案对我认为的问题没有任何新意,但我检查了错误并发现实际错误发生在这里:[-20, -10, 10, -70, 20, 30, -30] 将不能正确处理。它将排除正数 10,因此返回 50 而不是 60。

似乎询问者代码没有正确识别新的起始位置(我的方法显示在案例 4 中),重要的是在 Y 而不是 Z 处重新开始迭代,因为 Y 有效地删除了最低数字,这可能是未通过测试的 Z。

【讨论】:

OP 的代码为您的案例回答 20,事实上,我一直在努力想出一个案例让 OP 的代码失败但还没有找到一个案例 我看了他的测试,发现所有的错误都在一个元素的范围内,也许这是一个线索。

以上是关于MaxDoubleSliceSum 算法的主要内容,如果未能解决你的问题,请参考以下文章

python MaxDoubleSliceSum

Codility---MaxDoubleSliceSum

C语言编写程序,对一个double型数据进行四舍五入,要求保留两位有效小数,求算法。

swift算法手记-8

编程算法:有一个数类型为double,如何得到其个、十、百位上的数字?java、c描述都可以,速回速采纳,谢。

python 罗马数字乘法和除法使用half-and-double算法