1. 題目:

2. 題意分析:
給一個正整數,然後把它對應的每一個位上的數字用相應的羅馬數字表示,要注意特殊的那幾個的使用(4,9,40,90、、、、)。看到這個題我首先想到的就是以前遇到的一種題目,就是給買東西結賬時,有多少種方法(可能表述的不清楚,不是用支付寶、微信什麼的。而是假如要支付1元,而你手裏的錢有1角,五角,一元的,但是數目不限,問有哪些組合方法)。所以這一次我也是用那個思路來做的。
3. 解法一:
代碼:
class Solution:
def intToRoman(self, num):
num = str(num)
num_list = []
num_dict = {"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"}
for item in num:
if len(num) != 0:
row = "{0:0<{1}}".format(item, len(num))
if row in num_dict:
num_list.append(num_dict[row])
else:
n = "1"+row[1:] # 例如row是"300", 則n就是100
count = int(row[0]) # 那麼count就是3
if count > 5:
count_1 = 5*int(n)
count_2 = count-5
num_list.append("{0}".format(num_dict[str(count_1)]))
num_list.append(count_2*"{}".format(num_dict[n]))
else:
num_list.append(count*"{}".format(num_dict[str(n)]))
num = num[1:]
return "".join(num_list)
執行結果:


時間複雜度是O(n)=n
這兒有幾個關鍵點。
(1)如何通過數字轉化爲羅馬數字,我是選用字典的方法,先推出有哪些組合的方法,然後利用字典檢索就可以將對應的羅馬數字表示出來。
(2)例如給的數是738,那麼我就可以先得到這樣的組合(700+30+8),然後又細分得到這個組合(500+100+100+10+10+10+5+1+1+1),然後從字典中尋找出相應的羅馬數字,組合成一個字符串就可以了。
接下來就是如何優化。
3.解法二:
代碼:
class Solution:
def intToRoman(self, num):
num = str(num)
romes = ""
num_dict = {"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"}
for item in num:
if len(num) != 0:
row = "{0:0<{1}}".format(item, len(num))
if row in num_dict:
romes += num_dict[row]
num = num[1:]
continue
n = "1"+row[1:] # 例如row是"300", 則n就是100, 如果row是3,那麼n就是1
count = int(row[0]) # 那麼count就是3
if count > 5:
count_1 = 5*int(n) # 最高位用5代替,其餘的以0代替,例如n=700,那麼count_1=500
count_2 = count-5 # 獲取n的最高位與5相減的值,例如,n=700,那麼count_2=2
romes = romes + "{0}".format(num_dict[str(count_1)]) + count_2*"{}".format(num_dict[n])
num = num[1:]
continue
romes += count*"{}".format(num_dict[str(n)])
num = num[1:]
return romes
執行結果:


時間複雜度還是O(n)=n
代碼解釋:
(1)這個代碼和第一個變化不大,只是將不必要的條件判斷語句進行了刪改,對比執行結果,效果也不是很明顯。
4. 最優解法:
我將已提交結果裏的最優解複製了下來進行對比:
class Solution:
def intToRoman(self, num):
res = ''
token = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'), (100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'), (10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]
for n, t in token:
while num >= n:
res += t;
num -= n
return res
執行用時是116ms。而且人家這個代碼量。。。。。
5.總結:
最近好像有點思維定式了,老是一看到整數就想着轉化爲字符串來處理,但是幾次相同的經歷表明,python處理數字比字符串、列表等要快的多。