[Swift]LeetCode12. 整數轉羅馬數字 | Integer to Roman
阿新 • • 發佈:2018-10-31
Roman numerals are represented by seven different symbols: I
, V
, X
, L
, C
, D
and M
.
Symbol Value I 1 V 5 X 10 L 50 C 100 D 500 M 1000
For example, two is written as II
XII
, which is simply X
+ II
. The number twenty seven is written as XXVII
, which is XX
+ V
+ II
.
Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII
IV
. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX
. There are six instances where subtraction is used:
I
can be placed beforeV
(5) andX
(10) to make 4 and 9.X
can be placed beforeL
(50) andC
(100) to make 40 and 90.C
can be placed beforeD
(500) andM
(1000) to make 400 and 900.
Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999.
Example 1:
Input: 3 Output: "III"
Example 2:
Input: 4 Output: "IV"
Example 3:
Input: 9 Output: "IX"
Example 4:
Input: 58 Output: "LVIII" Explanation: C = 100, L = 50, XXX = 30 and III = 3.
Example 5:
Input: 1994 Output: "MCMXCIV" Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
羅馬數字包含以下七種字元: I
, V
, X
, L
,C
,D
和 M
。
字元 數值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000
例如, 羅馬數字 2 寫做 II
,即為兩個並列的 1。12 寫做 XII
,即為 X
+ II
。 27 寫做 XXVII
, 即為 XX
+ V
+ II
。
通常情況下,羅馬數字中小的數字在大的數字的右邊。但也存在特例,例如 4 不寫做 IIII
,而是 IV
。數字 1 在數字 5 的左邊,所表示的數等於大數 5 減小數 1 得到的數值 4 。同樣地,數字 9 表示為 IX
。這個特殊的規則只適用於以下六種情況:
I
可以放在V
(5) 和X
(10) 的左邊,來表示 4 和 9。X
可以放在L
(50) 和C
(100) 的左邊,來表示 40 和 90。C
可以放在D
(500) 和M
(1000) 的左邊,來表示 400 和 900。
給定一個整數,將其轉為羅馬數字。輸入確保在 1 到 3999 的範圍內。
示例 1:
輸入: 3 輸出: "III"
示例 2:
輸入: 4 輸出: "IV"
示例 3:
輸入: 9 輸出: "IX"
示例 4:
輸入: 58 輸出: "LVIII" 解釋: L = 50, V = 5, III = 3.
示例 5:
輸入: 1994 輸出: "MCMXCIV" 解釋: M = 1000, CM = 900, XC = 90, IV = 4.
40ms
1 class Solution { 2 func intToRoman(_ num: Int) -> String { 3 var roman:String = "" 4 var temp = num 5 while temp >= 1000 { 6 roman += "M" 7 temp = temp - 1000 8 } 9 10 while temp >= 900 { 11 roman += "CM" 12 temp = temp - 900 13 } 14 15 while temp >= 500 { 16 roman += "D" 17 temp = temp - 500 18 } 19 20 while temp >= 400 { 21 roman += "CD" 22 temp = temp - 400 23 } 24 25 while temp >= 100 { 26 roman += "C" 27 temp = temp - 100 28 } 29 30 while temp >= 90 { 31 roman += "XC" 32 temp = temp - 90 33 } 34 35 while temp >= 50 { 36 roman += "L" 37 temp = temp - 50 38 } 39 40 while temp >= 40 { 41 roman += "XL" 42 temp = temp - 40 43 } 44 45 while temp >= 10 { 46 roman += "X" 47 temp = temp - 10 48 } 49 50 while temp >= 9 { 51 roman += "IX" 52 temp = temp - 9 53 } 54 55 while temp >= 5 { 56 roman += "V" 57 temp = temp - 5 58 } 59 60 while temp >= 4 { 61 roman += "IV" 62 temp = temp - 4 63 } 64 65 while temp >= 1 { 66 roman += "I" 67 temp = temp - 1 68 } 69 return roman; 70 71 } 72 }
44ms
1 class Solution { 2 func intToRoman(_ num: Int) -> String { 3 var M:[String] = ["", "M", "MM", "MMM"] 4 var C:[String] = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"] 5 var X:[String] = ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"] 6 var I:[String] = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"] 7 8 return M[num/1000] + C[(num%1000)/100] + X[(num%100)/10] + I[num%10]; 9 } 10 }
48ms
1 class Solution { 2 3 struct romanSt { 4 var value:Int 5 var name:String 6 7 init(valueT:Int, nameT:String) { 8 value = valueT 9 name = nameT 10 } 11 } 12 13 func substractPart(_ partValue:romanSt, _ num:Int, _ romanStr:String) ->(value:String, temp:Int) { 14 var roman:String = romanStr 15 var temp = num 16 while temp >= partValue.value { 17 roman += partValue.name 18 temp = temp - partValue.value 19 } 20 return (roman, temp) 21 } 22 23 let romanStArray:Array<romanSt> = [romanSt(valueT: 1000, nameT: "M"), 24 romanSt(valueT: 900, nameT: "CM"), 25 romanSt(valueT: 500, nameT: "D"), 26 romanSt(valueT: 400, nameT: "CD"), 27 romanSt(valueT: 100, nameT: "C"), 28 romanSt(valueT: 90, nameT: "XC"), 29 romanSt(valueT: 50, nameT: "L"), 30 romanSt(valueT: 40, nameT: "XL"), 31 romanSt(valueT: 10, nameT: "X"), 32 romanSt(valueT: 9, nameT: "IX"), 33 romanSt(valueT: 5, nameT: "V"), 34 romanSt(valueT: 4, nameT: "IV"), 35 romanSt(valueT: 1, nameT: "I")] 36 37 func intToRoman(_ num: Int) -> String { 38 var roman:String = "" 39 var temp = num 40 41 for romanSt in romanStArray { 42 (roman, temp) = substractPart(romanSt, temp, roman) 43 } 44 45 return roman 46 } 47 }
52ms
1 extension String { 2 static func *(lhs: String, rhs: Int) -> String { 3 if rhs < 0 { 4 return "-\(lhs * abs(rhs))" 5 } 6 return String(repeating: lhs, count: rhs) 7 } 8 9 static func +(lhs: String, rhs: String) -> String { 10 if rhs.isEmpty { 11 return lhs 12 } else if rhs[rhs.startIndex] == "-" { 13 return "\(rhs[rhs.index(after: rhs.startIndex)...])\(lhs)" 14 } 15 return "\(lhs)\(rhs)" 16 } 17 } 18 19 enum Roman: String { 20 case I = "I" 21 case V = "V" 22 case X = "X" 23 case L = "L" 24 case C = "C" 25 case D = "D" 26 case M = "M" 27 28 var val: String { 29 get { 30 return self.rawValue 31 } 32 } 33 } 34 35 class Solution { 36 private func mapIntToRoman(_ num: Int) -> String { 37 if num < 10 { 38 return num < 4 39 ? Roman.I.rawValue * num 40 : (num == 9 41 ? Roman.I.rawValue + Roman.X.rawValue 42 : Roman.V.rawValue + Roman.I.rawValue * (num - 5)) 43 } else if num < 100 { 44 return num < 40 45 ? Roman.X.rawValue * (num / 10) 46 : (num == 90 47 ? Roman.X.rawValue + Roman.C.rawValue 48 : Roman.L.rawValue + Roman.X.rawValue * (num / 10 - 5)) 49 } else if num < 1000 { 50 return num < 400 51 ? Roman.C.rawValue * (num / 100) 52 : (num == 900 53 ? Roman.C.rawValue + Roman.M.rawValue 54 : Roman.D.rawValue + Roman.C.rawValue * (num / 100 - 5)) 55 } else { 56 return Roman.M.rawValue * (num / 1000) 57 } 58 } 59 60 func intToRoman(_ num: Int) -> String { 61 var last = num 62 var tens = 1 63 var result = "" 64 65 while last > 0 { 66 let remain = last % 10 * tens 67 let roman = mapIntToRoman(remain) 68 result = roman + result 69 last = last / 10 70 tens = tens * 10 71 } 72 return result 73 } 74 }
56ms
1 class Solution { 2 func intToRoman(_ num: Int) -> String { 3 var res = "" 4 var i = num 5 let dk = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] 6 let d = [1: "I", 5: "V", 10: "X", 50: "L", 100: "C", 500: "D", 1000: "M", 4: "IV", 9: "IX", 40: "XL", 90: "XC", 400: "CD", 900: "CM"] 7 8 while i > 0 { 9 for div in dk { 10 let kc = i / div 11 guard kc > 0 else { continue } 12 i -= (kc * div) 13 res.append(String(repeating: d[div]!, count: kc)) 14 } 15 } 16 return res 17 } 18 }
68ms
1 class Solution { 2 func intToRoman(_ num: Int) -> String { 3 var res = [Character]() 4 5 var num = num 6 7 res += Array(repeating: "M", count: num / 1000) 8 num = num % 1000 9 10 res += digitToRoman(num / 100, [1: "C", 5: "D", 10: "M"]) 11 num = num % 100 12 13 res += digitToRoman(num / 10, [1: "X", 5: "L", 10: "C"]) 14 num = num % 10 15 16 res += digitToRoman(num, [1: "I", 5: "V", 10: "X"]) 17 18 return String(res) 19 } 20 21 // map[1, 5, 10] 22 func digitToRoman(_ d: Int, _ map: [Int: Character]) -> [Character] { 23 if d <= 3 { 24 return Array(repeating: map[1]!, count: d) 25 } else if d == 4 { 26 return [map[1]!, map[5]!] 27 } else if d < 9 { 28 return [map[5]!] + Array(repeating: map[1]!, count: d-5) 29 } else { 30 return [map[1]!, map[10]!] 31 } 32 } 33 }
72ms
1 class Solution { 2 3 func intToRoman(_ num: Int) -> String { 4 let dict = ["I" : 1, "V" : 5, "X" : 10, "L" : 50, "C" : 100, "D" : 500, "M" : 1000] 5 let symbols = ["M", "D", "C", "L", "X", "V", "I"] 6 7 var result = "" 8 var divisor = 1000 9 var index = 0 10 var number = num 11 12 while divisor > 0 { 13 let quotient = number / divisor 14 if quotient > 0 { 15 switch quotient { 16 case 1...3: 17 for _ in 0..<quotient { 18 result += symbols[index] 19 } 20 case 4: 21 result += symbols[index] 22 result += symbols[index - 1] 23 case 5...8: 24 result += symbols[index - 1] 25 for _ in 5..<quotient { 26 result += symbols[index] 27 } 28 case 9: 29 result += symbols[index] 30 result += symbols[index - 2] 31 default: 32 break 33 } 34 number %= divisor 35 } 36 index += 2 37 divisor /= 10 38 } 39 40 return result 41 } 42 }
72ms
1 class Solution { 2 func intToRoman(_ num: Int) -> String { 3 var tempNum = num; 4 var ans = "" 5 6 var s = num / 1000 7 var h = num % 1000 / 100 8 var t = num % 100 / 10 9 var g = num % 10 10 11 while s > 0 { 12 ans += "M" 13 s -= 1 14 } 15 16 ans += getRoman(h, "C", "D", "M") 17 ans += getRoman(t, "X", "L", "C") 18 ans += getRoman(g, "I", "V", "X") 19 20 return ans 21 } 22 23 func getRoman(_ num: Int, _ one: String, _ five: String, _ ten: String) -> String { 24 var ans = "" 25 var tempNum = num; 26 27 if tempNum == 9 { 28 ans += one + ten 29 tempNum -= 9 30 } else if tempNum >= 5 { 31 ans += five 32 tempNum -= 5 33 } else if tempNum == 4 { 34 ans += one + five 35 tempNum -= 4 36 } 37 38 while tempNum > 0 { 39 ans += one 40 tempNum -= 1 41 } 42 43 return ans; 44 } 45 46 }
80ms
1 class Solution { 2 static let digits = [ 3 ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"], 4 ["X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"], 5 ["C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"], 6 ["M", "MM", "MMM"] 7 ] 8 9 func intToRoman(_ num: Int) -> String { 10 var answer = "" 11 answer.reserveCapacity(15) 12 var i = 3 13 var n = num 14 var p = 1000 15 while i >= 0 { 16 let j = n / p 17 if j != 0 { 18 answer.append(Solution.digits[i][j - 1]) 19 } 20 n = n % p 21 p = p / 10 22 i = i - 1 23 } 24 return answer 25 } 26 }