LeetCode539. 最小时间差

 539. 最小时间差

给定一个 24 小时制(小时:分钟 "HH:MM")的时间列表,找出列表中任意两个时间的最小时间差并以分钟数表示。

首先剪枝:一天共计1440分钟,时间超过1440个一定就会有重复值,根据抽屉原理,返回0;

方法一:哈希计数+寻找最小间距

先将string转int,一天共有1440分钟,我们开辟一个大小为1440的数组记录每个分钟的出现次数,然后遍历这个数组,寻找最小间距

class Solution {
    public int findMinDifference(List<String> timePoints) {
        int[]times=new int[1441];
        if(timePoints.size()>1440)return 0;
        for(int i=0;i<timePoints.size();i++){
            int time=parse(timePoints.get(i));
            System.out.println(time);
            if(time==0)times[1440]++;
            times[time]++;
        }
        int min=Integer.MAX_VALUE;
        for(int i=0;i<=1440;i++){
            if(times[i]==0)continue;
            if(times[i]>1)return 0;
            for(int j=i+1;j<=1440;j++){
                if(times[j]==0)continue;
                if(times[j]>1)return 0;
                int sub=j-i;
                min=Math.min(sub,min);
            }
        }
        return min;
    }
    int parse(String s){
        String hour=s.substring(0,2),min=s.substring(3,5);
        int h=Integer.parseInt(hour);
        int m=Integer.parseInt(min);
        return h*60+m;
    }
}

 但是我第一次写的代码有个问题,我把0和1440看成同一个时间,这样可以解决23:59和24:00的问题,但是这样我们面临一个问题,如果时间间隔最短是23:59和00:01这样的情况,我们计算出的结果是1438分钟,很明显不符合,所以我们要解决的问题就是,跨越一天的时间点怎么计算?

解决方式是,一次遍历,记录一天中第一个和最后一个时间点,同时寻找在“一天之内“最小的时间差,然后在把这个时间差和"跨天"的时间进行对比,但是跨天的时间我们不需要遍历,只需要拿"今天"的最后一个时间点和"明天"的第一个时间点做差,得到的一定是"跨天"时间差的最小值,然后再和"一天之内"最小的时间差比较,最小者就是答案

代码如下:

class Solution {
    public int findMinDifference(List<String> timePoints) {
        int[]times=new int[1440];
        if(timePoints.size()>1440)return 0;
        for(int i=0;i<timePoints.size();i++){
            int time=parse(timePoints.get(i));
            times[time]++;
        }
        int min=Integer.MAX_VALUE;
        //last记录上一个时间点,first记录第一个时间点
        //注意到一轮遍历完后,last记录的就是一天内最后一个时间点了
        int first=0,last=-1;
        for (int i = 0; i <1440; i++) {
            if (times[i] > 1) return 0;
            if (times[i] == 0) continue;
            if(last==-1){
                //初始化
                first=i;
            }else{

                //此处的last记录上一个时间点,作差然后更新最小值
                min=Math.min(min,i-last);
            }
            //last随时更新,记录当前最后一个时间点
            last=i;
        }
        // 首尾元素
        min= Math.min(min, first - last + 1440);
        return min;
    }
    int parse(String s){
        String hour=s.substring(0,2),min=s.substring(3,5);
        int h=Integer.parseInt(hour);
        int m=Integer.parseInt(min);
        return h*60+m;
    }
}

方法二:排序

还是面临方法一的问题,就是跨天的问题,此处我们的解决方式十分简单粗暴,每个时间点记录两次,一次今天一次明天,对于两个不同的时间点a和b这样就可以构成"同一天和a b""今天a明天b""今天b明天a"三种情况,然后遍历所有2n个时间点,选出最小的差值就是答案

注意每个时间点有两种情况,所以数组要开两倍

class Solution {
    public int findMinDifference(List<String> timePoints) {
        //当前时间和24小时之后,所以数组要开两倍
        int n = timePoints.size() * 2;
        int[] nums = new int[n];
        //一次更新两个,今天和明天
        for (int i = 0, idx = 0; i < n / 2; i++, idx += 2) {
            String[] ss = timePoints.get(i).split(":");
            int h = Integer.parseInt(ss[0]), m = Integer.parseInt(ss[1]);
            nums[idx] = h * 60 + m;
            nums[idx + 1] = nums[idx] + 1440;
        }
        //排序,然后找出最小值
        Arrays.sort(nums);
        //初始化
        int ans = nums[1] - nums[0];
        for (int i = 0; i < n - 1; i++) ans = Math.min(ans, nums[i + 1] - nums[i]);
        return ans;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值