[Swift]LeetCode539. 最小时间差 | Minimum Time Difference
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/10408567.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
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 小时制(小时:分钟)的时间列表,找出列表中任意两个时间的最小时间差并已分钟数表示。
示例 1:
输入: ["23:59","00:00"] 输出: 1
备注:
1.列表中时间数在 2~20000 之间。
2.
每个时间取值在 00:00~23:59 之间。
Runtime: 104 ms
Memory Usage: 20 MB
1 class Solution { 2 func findMinDifference(_ timePoints: [String]) -> Int { 3 var res:Int = Int.max 4 var pre:Int = 0 5 var first:Int = Int.max 6 var last:Int = Int.min 7 var mask:[Int] = [Int](repeating:0,count:1440) 8 for str in timePoints 9 { 10 var h:Int = Int(str.subString(0, 2))! 11 var m:Int = Int(str.subString(3))! 12 if mask[h * 60 + m] == 1 {return 0} 13 mask[h * 60 + m] = 1 14 } 15 for i in 0..<1440 16 { 17 if mask[i] == 1 18 { 19 if first != Int.max 20 { 21 res = min(res, i - pre) 22 } 23 first = min(first, i) 24 last = max(last, i) 25 pre = i 26 } 27 } 28 return min(res, 1440 + first - last) 29 } 30 } 31 32 extension String 33 { 34 // 截取字符串:指定索引和字符数 35 // - begin: 开始截取处索引 36 // - count: 截取的字符数量 37 func subString(_ begin:Int,_ count:Int) -> String { 38 let start = self.index(self.startIndex, offsetBy: max(0, begin)) 39 let end = self.index(self.startIndex, offsetBy: min(self.count, begin + count)) 40 return String(self[start..<end]) 41 } 42 43 // 截取字符串:从index到结束处 44 // - Parameter index: 开始索引 45 // - Returns: 子字符串 46 func subString(_ index: Int) -> String { 47 let theIndex = self.index(self.endIndex, offsetBy: index - self.count) 48 return String(self[theIndex..<endIndex]) 49 } 50 }
104ms
1 class Solution { 2 3 private let twentyFourHoursInMinutes = 24*60 4 5 func findMinDifference(_ timePoints: [String]) -> Int { 6 7 // constant space 8 var minuteBuckets = [Bool](repeating: false, count: twentyFourHoursInMinutes) 9 10 // O(N) time 11 for timeString in timePoints { 12 13 // O(1) time 14 let minutes = convertTimeStringToMinutes(timeString) 15 16 // if we already contain the `minutes`, that means the time difference will be 0 17 if minuteBuckets[minutes] { 18 return 0 19 } 20 21 minuteBuckets[minutes] = true 22 } 23 24 var minDifference = twentyFourHoursInMinutes 25 var firstMinute = 0 26 var lastMinute = -1 27 28 // O(1) time 29 for minute in 0..<minuteBuckets.count { 30 guard minuteBuckets[minute] else { 31 continue 32 } 33 34 if lastMinute == -1 { 35 firstMinute = minute 36 } else { 37 minDifference = min(minDifference, minute - lastMinute) 38 } 39 40 lastMinute = minute 41 } 42 43 minDifference = min(minDifference, firstMinute + (twentyFourHoursInMinutes - lastMinute)) 44 45 return minDifference 46 } 47 48 func convertTimeStringToMinutes(_ timeString: String) -> Int { 49 let hoursAndMinutes = timeString.split(separator: ":") 50 guard let hours = Int(hoursAndMinutes[0]), let minutes = Int(hoursAndMinutes[1]) else { 51 assertionFailure("...") 52 return 0 53 } 54 return (hours * 60) + minutes 55 } 56 }
108ms
1 class Solution { 2 func findMinDifference(_ timePoints: [String]) -> Int { 3 let timePointsSet = Set<String>(timePoints) 4 5 if (timePoints.count != timePointsSet.count) { 6 return 0 7 } 8 9 let timePoints = [String](timePointsSet).sorted() 10 11 12 var minResult = timeDifference(timePoints[0], timePoints[timePoints.count - 1]) 13 14 let maxIndex = timePoints.count - 2 15 for index in 0...maxIndex { 16 minResult = min(minResult, timeDifference(timePoints[index], timePoints[index+1])) 17 } 18 19 return minResult 20 } 21 22 private func timeDifference(_ time0 : String, _ time1 : String) -> Int { 23 var minutes0 = minutesFromTimeString(time0) 24 var minutes1 = minutesFromTimeString(time1) 25 26 if (minutes0 > minutes1) { 27 swap(&minutes0, &minutes1) 28 } 29 30 return min(minutes1 - minutes0, minutes0 + 24*60 - minutes1) 31 } 32 33 private func minutesFromTimeString(_ timeStr : String) -> Int { 34 let foundIndex = timeStr.firstIndex(of: ":") ?? timeStr.startIndex 35 let hourStr = timeStr[..<foundIndex] 36 let nextIndex = timeStr.index(after: foundIndex) 37 let minuteStr = timeStr[nextIndex...] 38 39 let hour = Int(hourStr)! 40 let minute = Int(minuteStr)! 41 42 return hour * 60 + minute 43 } 44 }
148ms
1 class Solution { 2 func getMinute(_ timePoint: String) -> Int { 3 var times = timePoint.split(separator: ":") 4 return Int(times[0])!*60 + Int(times[1])! 5 } 6 7 func findMinDifference(_ timePoints: [String]) -> Int { 8 if timePoints.count <= 1 { 9 return 0 10 } 11 12 var points: [Int] = timePoints.map { getMinute($0) } 13 points.sort() 14 15 var minn = 24*60 + points.first! - points.last! 16 17 for i in 1..<points.count { 18 minn = min(minn, points[i]-points[i-1]) 19 } 20 return minn 21 } 22 }
156ms
1 struct Time { 2 let hours: Int 3 let minutes: Int 4 } 5 6 extension Time: Comparable { 7 static func <(lhs: Time, rhs: Time) -> Bool { 8 return lhs.hours < rhs.hours || (lhs.hours == rhs.hours && lhs.minutes < rhs.minutes) 9 } 10 } 11 12 class Solution { 13 func findMinDifference(_ timePoints: [String]) -> Int { 14 15 let timePoints = timePoints 16 .map { convertToTime($0) } 17 .sorted() 18 19 var minDifference = Int.max 20 for i in 1..<timePoints.count { 21 minDifference = min( 22 minDifference, 23 calculateDifference(timePoints[i-1], timePoints[i])) 24 } 25 minDifference = min( 26 minDifference, 27 calculateDifference(timePoints[0], timePoints[timePoints.count-1])) 28 29 return minDifference 30 } 31 32 func calculateDifference(_ time1: Time, _ time2: Time) -> Int { 33 34 return min( 35 calculateDifference_helper(time1, time2), 36 calculateDifference_helper(time2, Time(hours: time1.hours+24, minutes: time1.minutes)) 37 ) 38 } 39 40 func calculateDifference_helper(_ time1: Time, _ time2: Time) -> Int { 41 return ((time2.hours - time1.hours) * 60) + (time2.minutes - time1.minutes) 42 } 43 44 func convertToTime(_ timeString: String) -> Time { 45 let timeUnits = timeString.split(separator: ":") 46 guard let hours = Int(timeUnits[0]), let minutes = Int(timeUnits[1]) else { 47 assertionFailure("...") 48 return Time(hours: 0, minutes: 0) 49 } 50 return Time(hours: hours, minutes: minutes) 51 } 52 }
164ms
1 typealias Time = (hours: Int, minutes: Int) 2 3 class Solution { 4 func findMinDifference(_ timePoints: [String]) -> Int { 5 6 var buckets = [[Int]](repeating: [Int](repeating: 0, count: 60), count: 24) 7 8 for timeString in timePoints { 9 let time = convertTimeString(timeString) 10 buckets[time.hours][time.minutes] += 1 11 } 12 13 var times: [Time] = [] 14 for hour in 0..<buckets.count { 15 for minutes in 0..<buckets[hour].count { 16 for _ in 0..<buckets[hour][minutes] { 17 times.append(Time(hour,minutes)) 18 } 19 } 20 } 21 22 var minDifference = Int.max 23 for i in 1..<times.count { 24 let difference = timeDifference(times[i-1], times[i]) 25 minDifference = min(minDifference, difference) 26 } 27 minDifference = min(minDifference, timeDifference(times[0], times[times.count-1])) 28 29 return minDifference 30 } 31 32 func timeDifference(_ time1: Time, _ time2: Time) -> Int { 33 let diff1 = timeDifference_helper(time1, time2) 34 let diff2 = timeDifference_helper(time2, (time1.hours+24, time1.minutes)) 35 return min(diff1, diff2) 36 } 37 38 func timeDifference_helper(_ time1: Time, _ time2: Time) -> Int { 39 return (time2.hours - time1.hours)*60 + (time2.minutes - time1.minutes) 40 } 41 42 func convertTimeString(_ timeString: String) -> Time { 43 let timeStringSplit = timeString.split(separator: ":") 44 guard let hours = Int(timeStringSplit[0]), let minutes = Int(timeStringSplit[1]) else { 45 return (0,0) 46 } 47 return (hours,minutes) 48 } 49 }
188ms
1 class Solution { 2 func getTime(_ time: String) -> Int { 3 let array = time.split(separator: ":") 4 guard array.count == 2 else { 5 return 0 6 } 7 8 let hours = Int(array[0])! 9 let minute = Int(array[1])! 10 11 return hours * 60 + minute 12 } 13 14 func findMinDifference(_ timePoints: [String]) -> Int { 15 let sorted = timePoints.sorted() 16 17 var minDiff = Int.max 18 let n = timePoints.count 19 20 for i in 0..<n { 21 var diff = getTime(sorted[(i - 1 + n) % n]) - getTime(sorted[i]) 22 diff = abs(diff) 23 diff = min(diff, 60 * 24 - diff) 24 minDiff = min(diff, minDiff) 25 } 26 27 return minDiff 28 } 29 }
208ms
1 class Solution { 2 3 func findMinDifference(_ timePoints: [String]) -> Int { 4 var sorted = timePoints.sorted() 5 var previous: String? 6 var diff = Int.max 7 for point in sorted { 8 guard let prev = previous else { 9 if let last = sorted.last { 10 let curDiff = timeDiff(point, last) 11 diff = min(diff, curDiff, 24 * 60 - curDiff) 12 } 13 previous = point 14 continue 15 } 16 let curDiff = timeDiff(point, prev) 17 diff = min(diff, curDiff, 24 * 60 - curDiff) 18 previous = point 19 } 20 return diff 21 } 22 23 func timeDiff(_ a: String, _ b: String) -> Int { 24 return abs(absTime(string: a) - absTime(string: b)) 25 } 26 27 func absTime(string: String) -> Int { 28 let split = string.split(separator: ":").map { Int($0)! } 29 return split[0] * 60 + split[1] 30 } 31 }