【问题标题】:Develop algorithm to get minimum number of subranges needed to cover range from 1 to n开发算法以获得覆盖范围从 1 到 n 所需的最小子范围数
【发布时间】:2023-03-05 10:11:01
【问题描述】:

谁能用一些伪代码和/或解释如何解决这个问题来帮助我解决这个问题?

给定一个范围列表 {start, stop} 和一个目标长度 n。一些范围将与其他范围重叠。开发一种算法来确定从 1 到 n 完全跨越所需的最小范围数。

例如,如果给定一个范围列表 [{1,2},{1,3},{2,3}] 和目标长度 n = 3,我应该返回 1,因为我们只需要{1,3} 涵盖从 1 到 3。显然,这是一个非常简单的测试用例。

有什么想法吗?我很困惑。我几乎想开发某种贪心算法,但我不确定这是否适合贪心解决方案......

【问题讨论】:

  • 到目前为止,我认为我应该首先按其开始元素对范围列表进行排序,但我不确定下一步该去哪里......
  • 让我们谈谈覆盖目标区间[a,b]而不仅仅是[1,n]。您有多个包含a 的区间。你需要一个吗?超过一个?哪个)?一旦你做出了选择,你现在需要解决什么样的问题?

标签: algorithm range intervals minimum greedy


【解决方案1】:

您可以使用Interval Tree。将区间放入数据结构中。

从 a = 1 开始。

在每一步都查询树中与 a 重叠且右端最大的区间。请注意,当您将区间树实现为增强的红黑树时,您可以使查询为您提供这两个条件。

将a的值重置为这个右端的值。

在查询返回结果时重复,每次将结果间隔存储在将成为答案的列表中。当 a >= n 时停止。

返回获得的列表。


证明上述结果具有最小基数

假设上面得到的区间序列,按左端排序为I1,I2,...,Im,分别调用a1,a2,...,am,右端。

如果 J1, J2, ..., Jr 是另一个区间序列,按它们的左端排序,覆盖 [1,n] 且 r 最小。呼叫 b1, b2, ..., br 他们的右端。

注意 J1 覆盖 1。因此 b1

因此,J2 涵盖 a1。你可以看到这是怎么回事。现在我们重复上面的论点。通过构造,b2

【讨论】:

  • 这如何为您提供最低限度?
【解决方案2】:

到目前为止,我在想我应该首先按它们的起始元素对范围列表进行排序,但我不确定下一步该去哪里......

是的,这是一个好的开始。

完成此操作后,您将遍历“可达”范围的“块”:

  • 首先,您扫描 start ≤ 1 的所有范围(意味着它们立即“可达”),并在这些范围中找到最大的 end — 调用max_end1.
  • 然后,您扫描所有具有 1 start ≤ max_end1 的范围(意味着您可以“到达”它们仅在一个先前的区间),并在 那些 范围中找到最大的 end — 称之为 max_end2
  • 继续这样做,直到达到某个 i 使得 max_endi ≥ n时间>。 i 就是答案。
  • 如果您到达可到达范围的“块”为空的点 - 您到目前为止的所有范围只能让您达到 x(其中 x n),并且下一个范围有 start > x,或者有 is 没有下一个范围——那么就没有回答,因为即使所有的间隔加在一起也不涵盖从 1 到 n 的范围。

请注意,虽然您只遍历排序列表一次,但如果您使用两个嵌套循环,实现起来可能会更简单:一个用于遍历“块”的外部循环,以及一个用于遍历“块”的外部循环。内部循环迭代每个“块”中的间隔。

【讨论】:

  • 好的,我想我正在关注。但是,我对如何使用两个嵌套循环实现它感到困惑。迭代“块”是什么意思?当你说一个块时,你的意思是从 1
  • 回复:“当你说一个块时,你的意思是从 1 start的范围> ≤ max_end₁。回复:“我对如何用两个嵌套循环实现它感到困惑”:请记住,并非所有循环都是 for 循环。您的外部循环可以是一个以chunk_start := next_chunk_start 结尾的while 循环,其中next_chunk_start 是在内部循环的过程中确定的。
猜你喜欢
  • 1970-01-01
  • 2022-08-10
  • 1970-01-01
  • 2019-11-11
  • 2021-09-03
  • 1970-01-01
  • 2019-05-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多