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:
- The number of time points in the given list is at least 2 and won’t exceed 20000.
- 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) }