我想我找到了解决方案。它至少适用于两个样本集。它不一定返回与答案相同的集合,但它返回的集合具有相同的最小值。它也是迭代和贪婪的,这很好,并且有很多方法可以优化它。看起来是 MLog(N)。
重要的是要认识到数字并不重要——只有它们之间的差异才重要。当你“删除一个数字”时,你实际上只是结合了两个相邻的差异。我的算法将专注于差异。回到哪些项目导致这些差异并随时删除是一件简单的事情。
算法
- 创建每个数字之间差异的有序列表/数组。
- 找出最小的差异x。如果 x 的计数 > 剩余的 M,则停止。您已经处于最佳状态。
- 对于从最左边开始的每个 x 值,将该差异与较低的相邻值组合(并删除该 x)。如果邻居的值相等,则您的决定是任意的。如果只有一个邻居的值为 x,则与另一个邻居合并。 (如果你别无选择,例如 [1, 1, ...],则与匹配的 X 组合,但如果可以,请避免。)
- 返回第 2 步,直到用完 M。
算法说明
第 3 步有一点我标记为任意决定。可能不应该是这样,但是您遇到了足够多的情况,这是您要添加多少复杂性的问题。这种任意性允许存在多个不同的正确答案。如果您看到两个具有相同值的邻居,此时,我说任意选择一个。理想情况下,您可能应该检查距离为 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 值的想法修改为避免这样做。