我有一个1,000,000个整数的列表。每个整数小于或等于100,000。
我必须找到第一个整数小于第二个整数的整数之差的最大总和,第二个整数大于第三个整数。允许第三个整数小于或大于第一个整数。此外,第一个整数必须位于第二个整数之前,第二个整数必须位于第三个整数之前。
我的解决方法如下:
1)运行循环提供的列表。
2)选择读取的当前整数后的最大整数。
3)找出它与当前整数之间的差异。
4)选择位于(2)部分中整数之后的最小整数。找出此整数与第(2)部分中找到的整数之间的差异。
5)将其添加到第(3)部分中找到的整数,并将该值存储为当前最高值。
6)重复此过程并根据需要替换当前最高值。
但是,我的解决方案算法没有时间限制(每个测试用例1秒)。对于一些测试用例来说,它也是不正确的。我使用C ++作为您的信息。
下面提供一个例子。
输入: 60 70 三十 50 40 60 20 10
输出:80
说明:列表中的第三,第六和第八个整数满足最佳条件。
我的问题:什么是解决此问题的最佳(最快)方法?
答案 0 :(得分:5)
您当前的算法不太正确,请考虑以下序列:
1,99,1,100,99
您当前的算法将选择以下情况(不同的情况对应于不同的起始位置):
1,100,99 score 100
99,100,99 score 2
1,100,99 score 100
然而,最佳选择是1,99,1,得分为98 * 2 = 196
复杂性也是O(n ^ 2),这将太慢。
AO(n)的方法是计算一个数组A [n],它给出0,1,..,n-1范围内的最小值,以及给出最小值的数组B [n]在n + 1,n + 2,..,结束范围内。
你可以在O(n)中计算这些,通过数组向前进行A,然后向后进行B。
一旦你拥有了这些,你可以通过数组进行第三次传递。对于每个索引i,您为第一个元素选择A [i],为中间元素选择i,为第三个元素选择B [i]。
你计算出这个组合的得分并保持最佳状态。
(您也可以将这些传递结合起来,以获得稍微复杂但可能更有效的解决方案。)
答案 1 :(得分:0)
你是从列表中选择三个连续的整数吗?
如果没有,那么清楚地对列表进行排序并选择最小,最大,最小的一直是赢家吗?
如果你必须使用列表中的三个连续整数,那么你真的别无选择,只能按顺序处理这些差异并保持最大值?
我解释这个问题意味着你必须选择三个整数,其中A,B,C在列表中以该顺序出现,但不一定是连续的,这是正确的吗?
如果是这样,想象一下将列表拆分为M个数的N个子序列。对于每个子序列,找到最大和最小的数字。
然后使用这些来选择最小,最大,最小或最大最小的最佳序列。
只要每个选择都在不同的子序列中,那么你就完成了。如果其中两个数字恰好位于相同的子序列中,那么您需要检查它们是否以正确的顺序出现。如果他们不这样做,则丢弃该解决方案并选择下一个最佳解决方案。
我建议可能选择大约1000个元素的子序列大小会使两个数字在同一序列中的概率非常低,并且仍会大大减少比较。
==============
替代答案
假设我们有两个连续的10个数字的子序列,并且你在每个中计算出最好的ABC,那么我有两个ABC序列,我可以轻松地将它们组合起来,只有几种方法来组合这些序列,并且其中一个组合必须是20个元素列表的最佳组合。
然后,您可以构建此动态样式。