我想我得到了解决方案。它至少适用于两个样本集。它不一定返回与答案相同的集合,但它返回的集合具有相同的最小值。它也是迭代和贪婪的,这很好,并且有很多方法可以优化它。看起来它是 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's。边缘上的移除只能在一个方向上添加:
[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值到避免这样做的想法进行了编辑。