12. Integer to Roman

題目鏈接
tag:

  • Medium

question:
??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 in Roman numeral, just two one's added together. Twelve is written as, 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. Instead, the number four is written as 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 before V (5) and X (10) to make 4 and 9.
  • X can be placed before L (50) and C (100) to make 40 and 90.
  • C can be placed before D (500) and M (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: L = 50, V = 5, III = 3.

Example 5

Input: 1994
Output: "MCMXCIV"
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.

之前那篇文章寫的是羅馬數(shù)字轉(zhuǎn)化成整數(shù) Roman to Integer萌腿, 這次變成了整數(shù)轉(zhuǎn)化成羅馬數(shù)字,基本算法還是一樣。由于題目中限定了輸入數(shù)字的范圍(1 - 3999), 使得題目變得簡單了不少。

例如整數(shù) 1437 的羅馬數(shù)字為 MCDXXXVII斩例, 我們不難發(fā)現(xiàn)惶我,千位,百位等曼,十位和個位上的數(shù)分別用羅馬數(shù)字表示了裂允。 1000 - M, 400 - CD, 30 - XXX, 7 - VII损离。所以我們要做的就是用取商法分別提取各個位上的數(shù)字,然后分別表示出來:

100 - C

200 - CC

300 - CCC

400 - CD

500 - D

600 - DC

700 - DCC

800 - DCCC

900 - CM

解法一:
我們可以分為四類绝编,100到300一類草冈,400一類,500到800一類瓮增,900最后一類怎棱。每一位上的情況都是類似的,代碼如下:

class Solution {
public:
    string intToRoman(int num) {
        string res = "";
        vector<char> roman{'M', 'D', 'C', 'L', 'X', 'V', 'I'};
        vector<int> value{1000, 500, 100, 50, 10, 5, 1};
        for (int n = 0; n < 7; n += 2) {
            int x = num / value[n];
            if (x < 4) {
                for (int i = 1; i <= x; ++i) res += roman[n];
            } else if (x == 4) {
                res = res + roman[n] + roman[n - 1]; 
            } else if (x > 4 && x < 9) {
                res += roman[n - 1];
                for (int i = 6; i <= x; ++i) res += roman[n];
            } else if (x == 9) {
                res = res + roman[n] + roman[n - 2];
            }
            num %= value[n];            
        }
        return res;
    }
};

解法二:
本題由于限制了輸入數(shù)字范圍這一特殊性绷跑,故而還有一種利用貪婪算法的解法拳恋,建立一個數(shù)表,每次通過查表找出當(dāng)前最大的數(shù)砸捏,減去再繼續(xù)查表谬运。參見代碼如下:

class Solution {
public:
    string intToRoman(int num) {
        string res = "";
        vector<int> val{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
        vector<string> str{"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
        for (int i = 0; i < val.size(); ++i) {
            while (num >= val[i]) {
                num -= val[i];
                res += str[i];
            }
        }
        return res;
    }
};

解法三:
下面這種方法個人感覺屬于比較投機(jī)取巧的方法,把所有的情況都列了出來垦藏,然后直接按位查表梆暖,O(1)的時間復(fù)雜度啊,參見代碼如下:

class Solution {
public:
    string intToRoman(int num) {
        string res = "";
        vector<string> v1{"", "M", "MM", "MMM"};
        vector<string> v2{"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
        vector<string> v3{"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
        vector<string> v4{"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
        return v1[num / 1000] + v2[(num % 1000) / 100] + v3[(num % 100) / 10] + v4[num % 10];
    }
};
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末掂骏,一起剝皮案震驚了整個濱河市轰驳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌弟灼,老刑警劉巖级解,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異田绑,居然都是意外死亡勤哗,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進(jìn)店門掩驱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芒划,“玉大人,你說我怎么就攤上這事欧穴∶癖疲” “怎么了?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵苔可,是天一觀的道長缴挖。 經(jīng)常有香客問我,道長焚辅,這世上最難降的妖魔是什么映屋? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮同蜻,結(jié)果婚禮上棚点,老公的妹妹穿的比我還像新娘。我一直安慰自己湾蔓,他們只是感情好瘫析,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般贬循。 火紅的嫁衣襯著肌膚如雪咸包。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天杖虾,我揣著相機(jī)與錄音烂瘫,去河邊找鬼。 笑死奇适,一個胖子當(dāng)著我的面吹牛坟比,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嚷往,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼葛账,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了皮仁?” 一聲冷哼從身側(cè)響起籍琳,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎魂贬,沒想到半個月后巩割,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡付燥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年宣谈,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片键科。...
    茶點(diǎn)故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡闻丑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出勋颖,到底是詐尸還是另有隱情嗦嗡,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布饭玲,位于F島的核電站侥祭,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏茄厘。R本人自食惡果不足惜矮冬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望次哈。 院中可真熱鬧胎署,春花似錦、人聲如沸窑滞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至巨坊,卻和暖如春撬槽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抱究。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工恢氯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鼓寺。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像勋磕,于是被迫代替她去往敵國和親妈候。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評論 2 355

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