[LeetCode] Minimum Time Difference 最短时间差

简介:

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. 

这道题给了我们一系列无序的时间点,让我们求最短的两个时间点之间的差值。那么最简单直接的办法就是给数组排序,这样时间点小的就在前面了,然后我们分别把小时和分钟提取出来,计算差值,注意唯一的特殊情况就是第一个和末尾的时间点进行比较,第一个时间点需要加上24小时再做差值,参见代码如下:

解法一:

public:
    int findMinDifference(vector<string>& timePoints) {
        int res = INT_MAX, n = timePoints.size(), diff = 0;
        sort(timePoints.begin(), timePoints.end());
        for (int i = 0; i < n; ++i) {
            string t1 = timePoints[i], t2 = timePoints[(i + 1) % n];
            int h1 = (t1[0] - '0') * 10 + t1[1] - '0';
            int m1 = (t1[3] - '0') * 10 + t1[4] - '0';
            int h2 = (t2[0] - '0') * 10 + t2[1] - '0';
            int m2 = (t2[3] - '0') * 10 + t2[4] - '0';
            diff = (h2 - h1) * 60 + (m2 - m1);
            if (i == n - 1) diff += 24 * 60;
            res = min(res, diff);
        }
        return res;
    }
};

下面这种写法跟上面的大体思路一样,写法上略有不同,是在一开始就把小时和分钟数提取出来并计算总分钟数存入一个新数组,然后再对新数组进行排序,再计算两两之差,最后还是要处理首尾之差,参见代码如下:

解法二:

public:
    int findMinDifference(vector<string>& timePoints) {
        int res = INT_MAX, n = timePoints.size();
        vector<int> nums;
        for (string str : timePoints) {
            int h = stoi(str.substr(0, 2)), m = stoi(str.substr(3));
            nums.push_back(h * 60 + m);
        }
        sort(nums.begin(), nums.end());
        for (int i = 1; i < n; ++i) {
            res = min(res, nums[i] - nums[i - 1]);
        }
        return min(res, 1440 + nums[0] - nums.back());
    }
};

上面两种方法的时间复杂度都是O(nlgn),我们来看一种O(n)时间复杂度的方法,由于时间点并不是无穷多个,而是只有1440个,所以我们建立一个大小为1440的数组来标记某个时间点是否出现过,如果之前已经出现过,说明有两个相同的时间点,直接返回0即可;若没有,将当前时间点标记为出现过。我们还需要一些辅助变量,pre表示之前遍历到的时间点,first表示按顺序排的第一个时间点,last表示按顺序排的最后一个时间点,然后我们再遍历这个mask数组,如果当前时间点出现过,再看如果first不为初始值的话,说明pre已经被更新过了,我们用当前时间点减去pre来更新结果res,然后再分别更新first,last,和pre即可,参见代码如下:

解法三:

public:
    int findMinDifference(vector<string>& timePoints) {
        int res = INT_MAX, pre = 0, first = INT_MAX, last = INT_MIN;
        vector<int> mask(1440, 0);
        for (string str : timePoints) {
            int h = stoi(str.substr(0, 2)), m = stoi(str.substr(3));
            if (mask[h * 60 + m] == 1) return 0;
            mask[h * 60 + m] = 1;
        }
        for (int i = 0; i < 1440; ++i) {
            if (mask[i] == 1) {
                if (first != INT_MAX) {
                    res = min(res, i - pre);
                }
                first = min(first, i);
                last = max(last, i);
                pre = i;
            }
        }
        return min(res, 1440 + first - last);
    }
};

参考资料:

https://discuss.leetcode.com/topic/83250/easy-c-solution

https://discuss.leetcode.com/topic/82573/verbose-java-solution-bucket

https://discuss.leetcode.com/topic/82575/java-o-nlog-n-o-n-time-o-1-space-solutions

本文转自博客园Grandyang,原文链接:[LeetCode] Minimum Time Difference 最短时间差

,如需转载请自行联系原博主。

相关文章
Leetcode Minimum Depth of Binary Tree (面试题推荐)
计算树的最小深度 很简单的一道题,只需要遍历一次树,到叶子节点的时候计算一下深度和当前最小深度比较,保存最小值就行。 我在这用了一个全局变量 mindepth。总感觉我这代码写的不够简练,求更精简的方法。
49 0
LeetCode Contest 178-1368. 使网格图至少有一条有效路径的最小代价 Minimum Cost to Make at Least One Valid Path in a Grid
LeetCode Contest 178-1368. 使网格图至少有一条有效路径的最小代价 Minimum Cost to Make at Least One Valid Path in a Grid
LeetCode 433. Minimum Genetic Mutation
现在给定3个参数 — start, end, bank,分别代表起始基因序列,目标基因序列及基因库,请找出能够使起始基因序列变化为目标基因序列所需的最少变化次数。如果无法实现目标变化,请返回 -1。
69 0
LeetCode 433. Minimum Genetic Mutation
|
存储 索引
LeetCode 310. Minimum Height Trees
对于一个具有树特征的无向图,我们可选择任何一个节点作为根。图因此可以成为树,在所有可能的树中,具有最小高度的树被称为最小高度树。给出这样的一个图,写出一个函数找到所有的最小高度树并返回他们的根节点。
75 0
LeetCode 310. Minimum Height Trees
LeetCode 209. Minimum Size Subarray Sum
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。
121 0
LeetCode 209. Minimum Size Subarray Sum
LeetCode 111. Minimum Depth of Binary Tree
给定一棵二叉树,返回其最短深度. 题目要求是返回一颗二叉树从根节点到到所有叶节点中,深度最小的值.
81 0
LeetCode 111. Minimum Depth of Binary Tree
LeetCode 64. Minimum Path Sum
给定m x n网格填充非负数,找到从左上到右下的路径,这最小化了沿其路径的所有数字的总和。 注意:您只能在任何时间点向下或向右移动。
105 0
LeetCode 64. Minimum Path Sum
|
人工智能 算法
LeetCode 1347. 制造字母异位词的最小步骤数 Minimum Number of Steps to Make Two Strings Anagram
LeetCode 1347. 制造字母异位词的最小步骤数 Minimum Number of Steps to Make Two Strings Anagram
|
索引
LeetCode 599: 两个列表的最小索引总和 Minimum Index Sum of Two Lists
题目: 假设 Andy 和 Doris 想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示。 Suppose Andy and Doris want to choose a restaurant for dinner, and they both have a list of favorite restaurants represented by strings. 你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅。
883 0
|
Java 索引 Python
LeetCode 209:最小长度的子数组 Minimum Size Subarray Sum
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。
579 0