给定一些整数范围,找到包含每个范围中至少一个整数的最小集合

时间:2013-02-21 14:40:47

标签: algorithm

如何找到一组最小整数,以便对于某些给定的整数范围,对于每个范围,该集包含至少一个整数。例如,如果我给出了这些范围:

[0, 4], [1, 2], [5, 7], [6, 7], [6, 9], [8, 10]

然后一些解决方案集是:{ 1, 6, 8 }, { 2, 7, 9 }, { 1, 7, 8 }等。

3 个答案:

答案 0 :(得分:4)

想象一下,您绘制所有范围,按结束值排序,就像在日程表中绘制会议一样。

您可以通过贪婪的方式直观地选择数字,这样第一个就是首先完成的细分(在您的示例中,这将是2)。

然后删除包含该号码的所有段,然后重新开始。

此算法将产生解决方案{ 2, 7, 10 }

0  1  2  3  4  5  6  7  8  9 10
   ----
-------------
      ^        -------
      |           ----
                  ----------
                     ^  -------
                     |        ^
                              |

答案 1 :(得分:3)

<强>算法: 对起点和终点进行排序。传递它们直到遇到端点。将其添加到答案中并删除已经传递的起始点的所有范围(即包含当前端点的范围)。重复,直到剩下任何一点。

示例:

[0, 4], [1, 2], [5, 7], [6, 7], [6, 9], [8, 10]

排序后将成为

[0, [1, 2], 4], [5, [6, [6, 7], 7], [8, 9], 10], ans = []

第一个端点为2],我们将其添加到ans并删除之前打开的范围,即[0[1

[5, [6, [6, 7], 7], [8, 9], 10], ans = [2]

现在第一个端点为7],我们移除范围[5, 7], [6, 7], [6, 9]

[8, 9], ans = [2, 7]

最后添加9并删除最后一个范围。结果将是[2, 7, 9]

<强>复杂度:

排序将花费O(nlogn)时间,之后你将传递每个元素两次:一次寻找下一个endpoing,一次删除所有当前打开的时间间隔,这是线性的,总复杂度将是{{1来自排序。

答案 2 :(得分:0)

我们按间隔号对间隔进行排序。对于任何间隔,如果其开始不大于上一个结束(由于对间隔进行了排序,则结束不小于上一个结束),则我们在上一个结束处有一个重叠,可以跳过此间隔。如果当前间隔的开始大于上一个结束,则我们没有重叠,并将当前结束添加到结果集中。

enter image description here

考虑间隔(0, 3), (2, 6), (3, 4), (6, 10)。排序后,我们有(0, 3), (3, 4), (2, 6), (6, 10)。我们从result = [3]previous = 3开始。从3 <= previous开始,我们跳过间隔(3, 4)previous保持不变。从2 <= previous开始,我们跳过间隔(2, 6)previous保持不变。最后,自6 > previous起,我们将10添加到结果中,并更新previous = 10。该算法终止;答案是[3, 10]

时间复杂度:n log(n),其中n是间隔数。