使用Go自带的container/heap实现最小时间差计算

container/heap简介

container/heap提供了具有堆序性质的基本框架,只需要实现响应的接口,便可获得一个优先队列

接口如下:

type Interface interface {
   sort.Interface
   Push(x interface{}) // add x as element Len()
   Pop() interface{}   // remove and return element Len() - 1.
}

其中,sort.Interface接口如下

type Interface interface {
   // Len is the number of elements in the collection.
   Len() int
   // Less reports whether the element with
   // index i should sort before the element with index j.
   Less(i, j int) bool
   // Swap swaps the elements with indexes i and j.
   Swap(i, j int)
}

实践

Given a list of 24-hour clock time points in “Hour:Minutes” format, find the minimum minutes difference between any two time points in the list.

Example 1:

Input: ["23:59","00:00"]
Output: 1

Note:

  1. The number of time points in the given list is at least 2 and won’t exceed 20000.
  2. The input time is legal and ranges from 00:00 to 23:59.

分析:求最短时间差,也就是说把00:00到23:59的分钟数从[0,24*60-1]的顺序排列起来并首尾相接,最短时间差只能出现在相邻的两个时间点;

相邻的两个时间点之差有两种情况:

1.两个点都在一天内:从小时间点到大时间点,next-pre<12*60,也就是小于[0,24*60-1]组成的圈的一半,此值可能为最小值

2.两个点跨越00:00,小值在大值的后一天:24*60+pre-next可能为最小值

因此我们可以先把给定的时间排序,然后依次求出相邻两个时间点之间最小差值,返回最小值即可

实现步骤就是,先实现一个优先队列,将数据入队,然后依次出队并计算差值

代码

type StrHeap []string // 使用字符串切片来存储数据,并实现heap的相关接口

func (h StrHeap) Len() int           { return len(h) }
func (h StrHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h StrHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }

func (h *StrHeap) Push(x interface{}) {
   *h = append(*h, x.(string))
}

func (h *StrHeap) Pop() interface{} {
   old := *h
   n := len(old)
   x := old[n-1]
   *h = old[0: n-1]
   return x
}

func findMinDifference(timePoints []string) int {
   h := StrHeap(timePoints) 
   heap.Init(&h) // 初始化堆
   ret := 24 * 60 
   pre := timeToInt(heap.Pop(&h).(string))
   first:=pre
   next:=24 * 60
   for h.Len() > 0 {
      // 依次取出每个值,求差
     next = timeToInt(heap.Pop(&h).(string))
      tmp := next - pre
      if tmp>12*60{
         tmp=24*60-tmp
      }
      if tmp < ret {
         ret = tmp
      }
      pre = next
   }
   // 最值有可能为首尾的差
  tmp := next - first
   if tmp>12*60{
      tmp=24*60-tmp
   }
   if tmp < ret {
      ret = tmp
   }
   return ret
}

//将字符串时间转换为分钟数,用以计算差值
func timeToInt(t string) int {
   fmt.Println(t)
   arr := strings.Split(t, ":")
   hour, _ := strconv.Atoi(arr[0])
   minute, _ := strconv.Atoi(arr[1])
   return hour*60 + minute
}

测试

func TestFindMinDifference(t *testing.T) {
   arr := []string{"08:01", "00:17", "14:12", "12:44", "06:06"}
   ret := findMinDifference(arr)
   fmt.Println(ret)
}
点赞