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.
這道題給了我們一系列無序的時間點,讓我們求最短的兩個時間點之間的差值。那么最簡單直接的辦法就是給數組排序,這樣時間點小的就在前面了,然后我們分別把小時和分鍾提取出來,計算差值,注意唯一的特殊情況就是第一個和末尾的時間點進行比較,第一個時間點需要加上24小時再做差值,參見代碼如下:
解法一:
class Solution { 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; } };
下面這種寫法跟上面的大體思路一樣,寫法上略有不同,是在一開始就把小時和分鍾數提取出來並計算總分鍾數存入一個新數組,然后再對新數組進行排序,再計算兩兩之差,最后還是要處理首尾之差,參見代碼如下:
解法二:
class Solution { 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即可,參見代碼如下:
解法三:
class Solution { 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