剑指offer 专项突破版 35、最小时间差

题目链接

思路
  • 暴力法就是挨个计算 因此是O(n²)
  • 在此基础上优化 可以先排序再计算相邻的时间间隔 O(nlogn)
  • 继续优化,因为排序的目的就是为了计算相邻时刻的时间间隔,因为题目中的时刻仅仅有60*24(1440)个,所以可以直接开一个长度为1440的boolean数组,用true代表有此时刻,那么相邻的时间间隔就是index2 - index1
    在此基础上有三点需要注意
    • 首先是输入时刻数目的长度,如果大于1440,那么必然有重复的,可以直接返回0
    • 其次是我们在改变数组内容时可以先检查一下该索引是不是true,如果是的话说明有相同时刻,可以直接返回0
    • 最后是我们在计算相邻两个时刻的时间差时,还需要考虑头和尾,需要把index1+1400-index2,也就是计算一下最后一个时刻距离第二天第一个时刻的时间差,ex:[00:00,01:00,23:59],最小时间间隔不是60,而是1
class Solution {
    public int findMinDifference(List<String> timePoints) {

        //必然会有重复的时间
        if (timePoints.size() > 1440)
            return 0;

        boolean[] minutesFlag = new boolean[1440];

        for (String time : timePoints) {
            String[] timePoint = time.split(":");
            int minute = Integer.parseInt(timePoint[0]) * 60 + Integer.parseInt(timePoint[1]);
            if(minutesFlag[minute])
                return 0;
            minutesFlag[minute] = true;
        }

        int minSpacing = Integer.MAX_VALUE, first = 1440, last = 0, pre = -1;

        for (int i = 0; i < minutesFlag.length; i++) {
            if (minutesFlag[i]) {
                if (pre > 0)
                    minSpacing = Math.min(minSpacing, i - pre);

                pre = i;
                first = Math.min(first, i);
                last = Math.max(last, i);
            }
        }
        return Math.min(minSpacing, 1440 + first - last);
    }
}

由于时间的特殊性,在计算间隔的时候需要额外计算跨天的时间,所以才会有

min := 1440 - minutes[len(minutes)-1] + minutes[0]
Go代码
func findMinDifference(timePoints []string) int {
	if len(timePoints) >= 1440 {
		return 0
	}

	minutes := make([]int, len(timePoints))
	for i, time := range timePoints {
		hour, _ := strconv.Atoi(time[0:2])
		minute, _ := strconv.Atoi(time[3:])
		minutes[i] = hour*60 + minute
	}
	sort.Ints(minutes)
	min := 1440 - minutes[len(minutes)-1] + minutes[0]
	for i := 0; i < len(minutes)-1; i++ {
		if minutes[i+1]-minutes[i] < min {
			min = minutes[i+1] - minutes[i]
		}
	}

	return min
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值