12. 整數(shù)轉(zhuǎn)羅馬數(shù)字

羅馬數(shù)字包含以下七種字符: I蜓洪, V纤勒, X, L隆檀,C摇天,D 和 M。

字符          數(shù)值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

例如恐仑, 羅馬數(shù)字 2 寫(xiě)做 II 泉坐,即為兩個(gè)并列的 1。12 寫(xiě)做 XII 菊霜,即為 X + II 坚冀。 27 寫(xiě)做 XXVII, 即為 XX + V + II 。

通常情況下鉴逞,羅馬數(shù)字中小的數(shù)字在大的數(shù)字的右邊记某。但也存在特例,例如 4 不寫(xiě)做 IIII构捡,而是 IV液南。數(shù)字 1 在數(shù)字 5 的左邊,所表示的數(shù)等于大數(shù) 5 減小數(shù) 1 得到的數(shù)值 4 勾徽。同樣地滑凉,數(shù)字 9 表示為 IX。這個(gè)特殊的規(guī)則只適用于以下六種情況:

  • I 可以放在 V (5) 和 X (10) 的左邊,來(lái)表示 4 和 9畅姊。
  • X 可以放在 L (50) 和 C (100) 的左邊咒钟,來(lái)表示 40 和 90。
  • C 可以放在 D (500) 和 M (1000) 的左邊若未,來(lái)表示 400 和 900朱嘴。

給定一個(gè)整數(shù),將其轉(zhuǎn)為羅馬數(shù)字粗合。輸入確保在 1 到 3999 的范圍內(nèi)萍嬉。

示例 4:
輸入: 58
輸出: "LVIII"
解釋: L = 50, V = 5, III = 3.

示例 5:
輸入: 1994
輸出: "MCMXCIV"
解釋: M = 1000, CM = 900, XC = 90, IV = 4.

解法一

沒(méi)看答案之前的做法,暴力求解法隙疚。
主要思路:從個(gè)位開(kāi)始壤追,遍歷出每一位,然后根據(jù)各種情況再表示出來(lái)供屉,并拼接到返回的字符串上行冰。

    # ['I', 'V', 'X', 'L', 'C', 'D', 'M']
    # [1,    5,   10,  50,  100, 500, 1000]

    def handleNum(cur, ns):
        if cur < 4:
            ns = 'I' * cur + ns
        elif cur == 4:
            ns = 'IV' + ns
        elif cur == 5:
            ns = 'V' + ns
        elif cur < 9:
            ns = 'V' + 'I' * (cur - 5) + ns
        elif cur == 9:
            ns = 'IX' + ns
        elif cur < 40:
            ns = 'X' * (cur // 10) + ns
        elif cur == 40:
            ns = 'XL' + ns
        elif cur == 50:
            ns = 'L' + ns
        elif cur < 90:
            ns = 'L' + 'X' * (cur // 10 - 5) + ns
        elif cur == 90:
            ns = 'XC' + ns
        elif cur < 400:
            ns = 'C' * (cur // 100) + ns
        elif cur == 400:
            ns = 'CD' + ns
        elif cur == 500:
            ns = 'D' + ns
        elif cur < 900:
            ns = 'D' + 'C' * (cur // 100 - 5) + ns
        elif cur == 900:
            ns = 'CM' + ns
        elif cur < 4000:
            ns = 'M' * (cur // 1000) + ns

        return ns

    # 先從個(gè)位開(kāi)始,表示每一位贯卦,再拼接起來(lái)
    ns, div = "", 10
    
    while True:
        # 這一位的數(shù)
        cur = num % div
        ns = handleNum(cur, ns)
        # 將這位去掉過(guò)后的整數(shù)
        num = num // div * div
        div *= 10

        # 最后一位资柔,計(jì)算出來(lái)就結(jié)束了
        if num // div == 0:
            cur = num
            ns = handleNum(cur, ns)
            break

    return ns

解法二

參考力扣官方答案焙贷,采用貪心算法撵割,貪心算法是一種在當(dāng)前時(shí)間做出最佳可能決策的算法。這里既是取出最大可能的符合辙芍。
主要思想:為了表示一個(gè)給定的整數(shù)啡彬,我們尋找適合它的最大符號(hào)。我們減去它故硅,然后尋找適合余數(shù)的最大符號(hào)庶灿,依此類(lèi)推,直到余數(shù)為0吃衅。我們?nèi)〕龅拿總€(gè)符號(hào)都附加到輸出的羅馬數(shù)字字符串上往踢。

def intToRoman2(num):

    digits = [(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")]
    # 記錄羅馬數(shù)字符號(hào)
    roman_digits = []
    # 從最大到最小循環(huán)遍歷每個(gè)符號(hào),檢查當(dāng)前符號(hào)的有多少個(gè)副本適合剩余的整數(shù)
    for value, symbol in digits:
        # 當(dāng)數(shù)字取完了過(guò)后就結(jié)束遍歷
        if num == 0: break
        # Return the tuple (x//y, x%y)
        count, num = divmod(num, value)
        # 將這位表示的羅馬數(shù)字符號(hào)添加到數(shù)組里面
        roman_digits.append(symbol * count)
    # 返回拼接起來(lái)的字符串
    return "".join(roman_digits)
復(fù)雜度分析
  • 時(shí)間復(fù)雜度:O(1)徘层。由于有一組有限的羅馬數(shù)字峻呕,循環(huán)可以迭代多少次有一個(gè)硬上限。因此趣效,我們說(shuō)時(shí)間復(fù)雜度是常數(shù)的瘦癌,即 O(1)。
  • 空間復(fù)雜度:O(1)跷敬,使用的內(nèi)存量不會(huì)隨輸入整數(shù)的大小而改變讯私,因此是常數(shù)的。

解法三

參考力扣官方答案,將每一位都表示出來(lái)斤寇,然后再逐位進(jìn)行計(jì)算和我的解法一有點(diǎn)相像桶癣。

主要思想:在代碼中實(shí)現(xiàn)它最簡(jiǎn)單的方法是使用 4 個(gè)獨(dú)立的數(shù)組;每個(gè)位置值對(duì)應(yīng)一個(gè)數(shù)組娘锁。然后鬼廓,在輸入數(shù)字中提取每個(gè)位置的數(shù)字,在相關(guān)數(shù)組中查找它們的符號(hào)致盟,并將它們?nèi)扛郊釉谝黄稹?/p>

def intToRoman3(num):
    thousands = ["", "M", "MM", "MMM"]
    hundreds = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"]
    tens = ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"]
    ones = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"]
    return thousands[num // 1000] + hundreds[num % 1000 // 100] + tens[num % 100 // 10] + ones[num % 10]
復(fù)雜度分析
  • 時(shí)間復(fù)雜度:O(1)碎税。無(wú)論輸入的大小,都會(huì)執(zhí)行相同數(shù)量的操作馏锡。因此雷蹂,時(shí)間復(fù)雜度是常數(shù)的。
  • 空間復(fù)雜度:O(1)杯道,雖然我們使用數(shù)組匪煌,但不管輸入的大小,它們都是相同的大小党巾。因此萎庭,它們是常數(shù)級(jí)空間。

力扣官方答案

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末齿拂,一起剝皮案震驚了整個(gè)濱河市驳规,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌署海,老刑警劉巖吗购,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異砸狞,居然都是意外死亡捻勉,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)刀森,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)踱启,“玉大人,你說(shuō)我怎么就攤上這事研底〔撼ィ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵飘哨,是天一觀的道長(zhǎng)胚想。 經(jīng)常有香客問(wèn)我,道長(zhǎng)芽隆,這世上最難降的妖魔是什么浊服? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任统屈,我火速辦了婚禮,結(jié)果婚禮上牙躺,老公的妹妹穿的比我還像新娘愁憔。我一直安慰自己,他們只是感情好孽拷,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布吨掌。 她就那樣靜靜地躺著,像睡著了一般脓恕。 火紅的嫁衣襯著肌膚如雪膜宋。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,246評(píng)論 1 308
  • 那天炼幔,我揣著相機(jī)與錄音秋茫,去河邊找鬼。 笑死乃秀,一個(gè)胖子當(dāng)著我的面吹牛肛著,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播跺讯,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼坚嗜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼灵汪!你這毒婦竟也來(lái)了今缚?” 一聲冷哼從身側(cè)響起欠橘,我...
    開(kāi)封第一講書(shū)人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤押袍,失蹤者是張志新(化名)和其女友劉穎匪蝙,沒(méi)想到半個(gè)月后祟印,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體温学,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年钙畔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片金麸。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡擎析,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出挥下,到底是詐尸還是另有隱情揍魂,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布棚瘟,位于F島的核電站现斋,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏偎蘸。R本人自食惡果不足惜庄蹋,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一瞬内、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧限书,春花似錦虫蝶、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至扰柠,卻和暖如春粉铐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背卤档。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工秦躯, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人裆装。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓踱承,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親哨免。 傳聞我的和親對(duì)象是個(gè)殘疾皇子茎活,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容