我想我找到了解决方案。它在两个样本集上有效,至少如此。它不一定返回与答案相同的集合,但是返回的集合具有相同的最小值。它是迭代和贪婪的,这很好,而且有很多优化方法。看起来它的时间复杂度是MLog(N)。
重要的是要意识到数字并不重要 - 只有它们之间的差异才重要。当你“删除一个数字”时,实际上只是将两个相邻的差异合并在一起。我的算法将关注这些差异。回到导致这些差异的项目并随着进程删除是一件简单的事情。
算法
- 创建一个有序列表/数组,列出每个数字之间的差异。
- 找到最小差异 x。如果 x 的计数 > 剩余的 M,则停止。您已经处于最佳情况。
- 对于从最左边开始的每个 x 值,将该差异与较低的相邻值组合(并删除该 x)。如果相邻值相等,则您的决定是任意的。如果只有一个相邻值的值为 x,则与另一个相邻值组合。(如果没有选择,例如 [1, 1, ...],则与匹配的 X 组合,但如果可以避免则避免。)
- 回到步骤 2,直到用完 M。
算法说明
第三步有一个我标记为任意决定的点。它可能不应该是这样,但你已经涉及到足够复杂的情况,这是一个关于你想要添加多少复杂性的问题。这种武断性是允许存在多个不同正确答案的原因。如果你看到两个相邻的数值相同,在这一点上,我会随意选择一个。理想情况下,你应该检查相距2、3等的邻居对,并倾向于较低的那个。如果你在扩展时遇到边缘,我不确定该怎么办。最终,为了完美地完成这一部分,你可能需要递归调用这个函数,并看哪个评估更好。
走过样本数据:
先看第二个:
从以下数字中删除至多8个:
0 3 7 10 15 26 38 44 53 61 76 80 88 93 100
[3, 4, 3, 5, 11, 12, 6, 9, 8, 15, 4, 8, 5, 7] M = 8
删除3. 边缘上的移除只能朝一个方向添加:
[7, 3, 5, 11, 12, 6, 9, 8, 15, 4, 8, 5, 7] M = 7
[7, 8, 11, 12, 6, 9, 8, 15, 4, 8, 5, 7] M = 6
接下来,移除4:[7, 8, 11, 12, 6, 9, 8, 15, 12, 5, 7] M = 5
接下来,移除5:[7, 8, 11, 12, 6, 9, 8, 15, 12, 12] M = 4
接下来,移除6:[7, 8, 11, 12, 15, 8, 15, 12, 12] M = 3
接下来,移除7:[15, 11, 12, 15, 8, 15, 12, 12] M = 2
接下来,删除8:[15, 11, 12, 15, 23, 12, 12] M = 1 // 注意,添加方向是任意决定的
最后,删除11:[15, 23, 15, 23, 12, 12]
请注意,在答案中,最小差为12。
先处理第一个
从以下数据中最多删除7个:
0 3 7 10 15 18 26 31 38 44 53 60 61 73 76 80 81 88 93 100
[3, 4, 3, 5, 3, 8, 5, 7, 6, 9, 7, 1, 12, 3, 4, 1, 7, 5, 7] M = 7
删除1:
[3, 4, 3, 5, 3, 8, 5, 7, 6, 9, 8, 12, 3, 4, 1, 7, 5, 7] M = 6
[3, 4, 3, 5, 3, 8, 5, 7, 6, 9, 8, 12, 3, 5, 7, 5, 7] M = 5
还剩下4个3,所以我们可以将它们移除:
[7, 3, 5, 3, 8, 5, 7, 6, 9, 8, 12, 3, 5, 7, 5, 7] M = 4
[7, 8, 3, 8, 5, 7, 6, 9, 8, 12, 3, 5, 7, 5, 7] M = 3
[7, 8, 11, 5, 7, 6, 9, 8, 12, 3, 5, 7, 5, 7] M = 2 // 注意任意添加到右侧
[7, 8, 11, 5, 7, 6, 9, 8, 12, 8, 5, 7, 5, 7] M = 1
我们接下来会移除5,但是只允许移除1个,而我们只有3个,所以我们就停在这里。我们的最小差值为5,与解决方案相匹配。
注意:从SauceMaster提出的1、29、30、31、59情况中,编辑了将相同的X值组合在一起的想法,以避免这样做。