[Swift]LeetCode937. 重新排列日志文件 | Reorder Log Files
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/9942450.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
You have an array of logs
. Each log is a space delimited string of words.
For each log, the first word in each log is an alphanumeric identifier. Then, either:
- Each word after the identifier will consist only of lowercase letters, or;
- Each word after the identifier will consist only of digits.
We will call these two varieties of logs letter-logs and digit-logs. It is guaranteed that each log has at least one word after its identifier.
Reorder the logs so that all of the letter-logs come before any digit-log. The letter-logs are ordered lexicographically ignoring identifier, with the identifier used in case of ties. The digit-logs should be put in their original order.
Return the final order of the logs.
Example 1:
Input: ["a1 9 2 3 1","g1 act car","zo4 4 7","ab1 off key dog","a8 act zoo"]
Output: ["g1 act car","a8 act zoo","ab1 off key dog","a1 9 2 3 1","zo4 4 7"]
Note:
0 <= logs.length <= 100
3 <= logs[i].length <= 100
logs[i]
is guaranteed to have an identifier, and a word after the identifier.
你有一个日志数组 logs
。每条日志都是以空格分隔的字串。
对于每条日志,其第一个字为字母数字标识符。然后,要么:
- 标识符后面的每个字将仅由小写字母组成,或;
- 标识符后面的每个字将仅由数字组成。
我们将这两种日志分别称为字母日志和数字日志。保证每个日志在其标识符后面至少有一个字。
将日志重新排序,使得所有字母日志都排在数字日志之前。字母日志按字母顺序排序,忽略标识符,标识符仅用于表示关系。数字日志应该按原来的顺序排列。
返回日志的最终顺序。
示例 :
输入:["a1 9 2 3 1","g1 act car","zo4 4 7","ab1 off key dog","a8 act zoo"] 输出:["g1 act car","a8 act zoo","ab1 off key dog","a1 9 2 3 1","zo4 4 7"]
提示:
0 <= logs.length <= 100
3 <= logs[i].length <= 100
logs[i]
保证有一个标识符,并且标识符后面有一个字。
1 class Solution { 2 func reorderLogFiles(_ logs: [String]) -> [String] { 3 var digitLogs = [String]() 4 var letterLogs = [String]() 5 var keys = [String]() 6 var letterDic = [String:String]() 7 for log in logs { 8 if log.last! >= "a" && log.last! <= "z" { 9 var index = 0 10 let length = log.count 11 for char in log { 12 if char == " " { 13 let suffix = String(log.suffix(length-index-1)) 14 letterDic[suffix] = log 15 keys.append(suffix) 16 break 17 } 18 index += 1 19 } 20 }else { 21 digitLogs.append(log) 22 } 23 } 24 keys = keys.sorted() 25 for key in keys { 26 letterLogs.append(letterDic[key] ?? "") 27 } 28 return letterLogs+digitLogs 29 } 30 }
96ms
1 class Solution { 2 struct Log { 3 let identifier: String 4 let content: String 5 let orig: String 6 let isLetter: Bool 7 8 init(_ orig: String) { 9 self.orig = orig 10 11 let index = orig.firstIndex(of: " ")! 12 self.identifier = String(orig[orig.startIndex..<index]) 13 self.content = String(orig[orig.index(after:index)...]) 14 self.isLetter = Int(String(self.content.first!)) == nil 15 } 16 } 17 func reorderLogFiles(_ logs: [String]) -> [String] { 18 19 let logsArr: [Log] = logs.map { Log($0) } 20 var letters = logsArr.filter { $0.isLetter } 21 var digits = logsArr.filter { !$0.isLetter } 22 23 letters.sort { 24 if $0.content == $1.content { 25 return $0.identifier < $1.identifier 26 } else { 27 return $0.content < $1.content 28 } 29 } 30 31 return [letters, digits].flatMap { arr in 32 return arr.map { $0.orig } 33 } 34 } 35 }
104ms
1 class Solution { 2 func reorderLogFiles(_ logs: [String]) -> [String] { 3 4 let letters = logs.filter { 5 let lastChar = $0.charAt($0.count - 1) 6 return CharacterSet.letters.contains(lastChar.unicodeScalars.first!) 7 }.map { 8 $0.split(separator: " ") 9 }.map { 10 (Array($0[1..<$0.count]).joined(separator: " "), $0[0]) 11 }.sorted { 12 return $0.0 < $1.0 13 } 14 15 let digits = logs.filter { 16 let lastChar = $0.charAt($0.count - 1) 17 return CharacterSet.decimalDigits.contains(lastChar.unicodeScalars.first!) 18 } 19 20 return letters.map { $0.1 + " " + $0.0 } + digits 21 } 22 } 23 24 extension String { 25 func charAt(_ pos:Int) -> String { 26 guard pos < self.count else { 27 assertionFailure("Index out of range!") 28 return String() 29 } 30 let index = self.index(self.startIndex, offsetBy: pos) 31 return String(self[index]) 32 } 33 }
108ms
1 class Solution { 2 func reorderLogFiles(_ logs: [String]) -> [String] { 3 var letters = [String](); 4 var digits = [String](); 5 var output = [String](); 6 for log in logs{ 7 let elements = log.split(separator: " "); 8 let firstElement = elements[1]; 9 var isLetter = false; 10 for char in firstElement.utf8{ 11 if (char >= "a".utf8.first! && char <= "z".utf8.first!){ 12 isLetter = true; 13 break; 14 } 15 } 16 if isLetter{ 17 letters.append(log); 18 }else{ 19 digits.append(log); 20 } 21 } 22 letters.sort(by: {(a:String,b:String)->Bool in 23 var index = a.firstIndex(of: " "); 24 index = a.index(index!, offsetBy: 1) 25 let suffixA = a.suffix(from: index!) 26 index = b.firstIndex(of: " ") 27 index = b.index(index!, offsetBy: 1) 28 let suffixB = b.suffix(from: index!) 29 return suffixA < suffixB; 30 }) 31 for str in letters{ 32 output.append(str) 33 } 34 for str in digits{ 35 output.append(str) 36 } 37 return output; 38 } 39 }
112ms
1 class Solution { 2 func reorderLogFiles(_ logs: [String]) -> [String] { 3 guard logs.count > 0 else { 4 return [] 5 } 6 var result : [String] = [] 7 var alphaLogDictionary : [String : (identifier : String, word : String)] = [:] 8 var digitLogArray : [String] = [] 9 10 for log in logs{ 11 if isDigitLog(log){ 12 digitLogArray.append(log) 13 }else{ 14 alphaLogDictionary[log] = dissectAlphaLog(log) 15 } 16 } 17 18 let sortedAlpha = alphaLogDictionary.sorted { (first, second) -> Bool in 19 if first.value.word == second.value.word{ 20 return first.value.identifier < second.value.identifier 21 }else{ 22 return first.value.word < second.value.word 23 } 24 } 25 26 for pair in sortedAlpha{ 27 result.append(pair.key) 28 } 29 for value in digitLogArray{ 30 result.append(value) 31 } 32 33 return result 34 35 } 36 37 private func dissectAlphaLog(_ s : String)->(identifier : String, word : String){ 38 var str = Array(s) 39 var movingIndex : Int = 0 40 var identifier : String = "" 41 var word : String = "" 42 while movingIndex < str.count{ 43 if str[movingIndex] != " "{ 44 movingIndex += 1 45 }else{ 46 identifier = String(str[0..<movingIndex]) 47 word = String(str[movingIndex..<str.count]) 48 return (identifier : identifier, word : word) 49 } 50 } 51 52 return (identifier : "", word : "") 53 54 } 55 56 private func isDigitLog(_ s : String)->Bool{ 57 var movingIndex : Int = 0 58 var str = Array(s) 59 var char : Character = Character.init("a") 60 while movingIndex < str.count { 61 if str[movingIndex] != " "{ 62 movingIndex += 1 63 }else{ 64 char = str[movingIndex + 1] 65 break 66 } 67 } 68 69 let letterSet = CharacterSet.letters 70 if letterSet.contains(char.unicodeScalars.first!){ 71 return false 72 }else{ 73 return true 74 } 75 } 76 }
120ms
1 class Solution { 2 func reorderLogFiles(_ logs: [String]) -> [String] { 3 var n:Int = logs.count 4 var ss:[[String]] = [[String]](repeating: [String](), count: n) 5 for i in 0..<n 6 { 7 let str:String = logs[i] 8 var end = str.firstIndex(of: " ") ?? str.endIndex 9 //不包括结束索引 10 var id:String = String(str[str.startIndex..<end]) 11 let start = end == str.endIndex ? str.endIndex : str.index(end, offsetBy: 1) 12 var rem:String = String(str[start..<str.endIndex]) 13 ss[i] = [rem, id, str, String(format: "%05d",i)] 14 } 15 ss.sort(by: compare) 16 var ret:[String] = [String] (repeating:String(),count: n) 17 for i in 0..<n 18 { 19 ret[i] = ss[i][2] 20 } 21 return ret 22 } 23 24 func compare(_ a:[String],_ b:[String]) -> Bool 25 { 26 //'0':ASCII码值 48; '9'ASCII码值 57 27 var num1:Int = a[0].toInt(0) 28 var ad:Bool = num1 >= 48 && num1 <= 57 29 30 var num2:Int = b[0].toInt(0) 31 var bd:Bool = num2 >= 48 && num2 <= 57 32 33 if !ad && bd{return true} 34 if ad && !bd{return false} 35 var str1:String 36 var str2:String 37 if !ad && !bd 38 { 39 if a[0] != b[0] 40 { 41 str1 = a[0] 42 str2 = b[0] 43 } 44 else 45 { 46 str1 = a[1] 47 str2 = b[1] 48 } 49 } 50 else 51 { 52 str1 = a[3] 53 str2 = b[3] 54 } 55 let num = str1.caseInsensitiveCompare(str2).rawValue 56 if num == -1 57 { 58 return true 59 } 60 return false 61 } 62 } 63 64 extension String { 65 //获取指定索引位置的字符,返回为字符串形式 66 func charAt(_ num:Int) -> String 67 { 68 return String(self[index(self.startIndex,offsetBy: num)]) 69 } 70 71 //获取指定索引位置字符的ASCII整数值 72 func toInt(_ num:Int) -> Int 73 { 74 let s = charAt(num).unicodeScalars 75 return Int(s[s.startIndex].value) 76 } 77 }
124ms
1 extension Array { 2 mutating func stableSort(by areInIncreasingOrder: (Array<Element>.Element, Array<Element>.Element) -> Bool) { 3 for startIdx in startIndex..<endIndex { 4 for targetIdx in index(after:startIdx)..<endIndex { 5 if !areInIncreasingOrder(self[startIdx], self[targetIdx]) { 6 let tmp = self[startIdx] 7 self[startIdx] = self[targetIdx] 8 self[targetIdx] = tmp 9 } 10 } 11 } 12 } 13 } 14 15 extension String { 16 var cdr:Substring? { 17 return split(separator: " ", maxSplits: 1).last 18 } 19 } 20 class Solution { 21 func reorderLogFiles(_ logs: [String]) -> [String] { 22 let digiLogs = logs.filter{Int($0[$0.index(before:$0.endIndex)..<$0.endIndex]) != nil} 23 var letterLogs = logs.filter{Int($0[$0.index(before:$0.endIndex)..<$0.endIndex]) == nil} 24 letterLogs.sort() 25 letterLogs.stableSort{String($0.cdr!) < String($1.cdr!)} 26 return letterLogs + digiLogs 27 } 28 }
132ms
1 class Solution { 2 func getLogStr(_ s: String) -> Substring { 3 return s.suffix(from: s.index(after: s.firstIndex(of: " ")!)) 4 } 5 func isDig(_ s: String) -> Bool { 6 let digits = Character("0")...Character("9") 7 let l = getLogStr(s) 8 return digits.contains(l[l.startIndex]) 9 } 10 func cmp(_ a: String, _ b: String) -> Bool { 11 let la = getLogStr(a) 12 let lb = getLogStr(b) 13 if la == lb { return a < b } 14 return la < lb 15 } 16 func reorderLogFiles(_ logs: [String]) -> [String] { 17 let dig = logs.filter(isDig) 18 let alp = logs.filter{!isDig($0)} 19 return alp.sorted(by: cmp) + dig 20 } 21 }
140ms
1 class Solution { 2 func reorderLogFiles(_ logs: [String]) -> [String] { 3 let one = logs.filter { (str) -> Bool in 4 Int(String(String(str.split(separator: " ")[1]).first!)) != nil 5 } 6 7 var two = logs.filter { (str) -> Bool in 8 Int(String(String(str.split(separator: " ")[1]).first!)) == nil 9 } 10 11 two.sort { (a, b) -> Bool in 12 let arrayOne = a.split(separator: " ") 13 let arrayTwo = b.split(separator: " ") 14 let str_one = String(arrayOne[1...].joined(separator: " ")) 15 let str_two = String(arrayTwo[1...].joined(separator: " ")) 16 return str_one<str_two 17 } 18 19 return two + one 20 } 21 }