Go语言实现Union of Intervals

描述

Write a function interval_insert which takes as input
a list myl of disjoint closed intervals with integer endpoints, sorted by increasing order of left endpoints
an interval interval
and returns the union of interval with the intervals in myl, as an array of disjoint closed intervals.
Terminology
A closed interval includes its endpoints. For example [0,5] means greater than or equal to 0 and less than or equal to 5. For more, refer to Wikipedia.
Two intervals are said to be disjoint if they have no element in common. Equivalently, disjoint intervals are intervals whose intersection is the empty interval. For example,
[1,3] and [4,6] are disjoint
[1,3] and [3,5] are not.
Examples:
[(1, 2)], (3, 4) -> [(1, 2), (3, 4)]
[(3, 4)], (1, 2) -> [(1, 2), (3, 4)]
[(1, 2), (4, 6)], (1, 4) -> [(1, 6)]
[(0, 2), (3, 6), (7, 7), (9, 12)], (1, 8) -> [(0, 8), (9, 12)]

分析

**方法1:**运用递归。我们只关注区间段数组的第一个区间段元素与欲插入区间段的关系。两者之间只有3种可能:第一种是欲插入区间段在第一个区间段元素左侧无交集;第二种是欲插入区间段与第一个区间段元素有交集;第三种是欲插入区间段在第一个区间段元素右侧无交集。对于第一种情况,结果就是在数组起始位置添加欲插入区间段;对于第二种情况,欲插入区间段与第一个区间段元素合并后,形成了该问题的新的同性质的子问题,即对于原区间段数组第二个区间段元素开始的子区间段数组,与合并后的欲插入区间段元素的问题。对于第三种情况,结果数组第一个元素就是原数组第一个元素,之后的子数组同样形成了该问题的新的同性质的子问题,即对于原区间段数组第二个区间段元素开始的子区间段数组,与欲插入区间段元素的问题。递归终止条件是区间段数组为空,此时结果就是欲插入区间段。
**方法2:**运用递推。首先依序遍历区间段数组,跳过没有交集的区间段元素。之后对于接下来的元素,只有两种可能,一种是在元素左侧,结果就是跳过的元素子集连接欲插入区间段再连接后续元素子集。另一种是与元素有交集,这种情况首先合并欲插入区间段与该元素,然后以该合并后的区间段继续和后续元素进行比较。

实现

方法1:

func min(a, b int) int {
  if a < b { return a}
  return b
}

func max(a, b int) int {
  if a > b { return a}
  return b
}

func IntervalInsert(r [][2]int,z [2]int) [][2]int {
  if len(r) == 0 { return [][2]int{ z } }
  switch {
  case z[1] < r[0][0]:
    return append([][2]int{ z }, r...)
  case z[1] >=r[0][0] && z[0] <= r[0][1]:
    return IntervalInsert(r[1:], [2]int{ min(z[0], r[0][0]), max(z[1], r[0][1])})
  }
  return append([][2]int{ r[0] }, IntervalInsert(r[1:], z)...)
}

方法2:

func min(a, b int) int {
  if a < b { return a}
  return b
}

func max(a, b int) int {
  if a > b { return a}
  return b
}

func IntervalInsert(r [][2]int,z [2]int) [][2]int {
  i, j := 0, 0
  for i < len(r) && r[i][1] < z[0] { i++ }
  for _, v := range r[i:] {
    if z[1] < v[0] { break }
    z = [2]int{ min(z[0],v[0]), max(z[1],v[1]) }
    j++
  }
  return append(append(append([][2]int{}, r[:i]...), z), r[i+j:]...)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值