string 找出所有数字 index_发现规律,解决整数转罗马数字
| 字符 | 數值 |
| I | 1 |
| V | 5 |
| X | 10 |
| L | 50 |
| C | 100 |
| D | 500 |
| M | 1000 |
通常情況下,羅馬數字中小的數字在大的數字的右邊。但也存在特例,例如 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.02?. 思路分析這道題整體看起來有明確的規則,只需要梳理清楚羅馬數字的表示規律即可,那我們現在就開始發現規律:跟我們常用的阿拉伯數字表示十進制數字相同,羅馬數字也通過十進制來表示,只是比我們的 0 1 2 3 4 5 的阿拉伯數字復雜一些,而且每一位用的是不同的字母表示。我們先把?0 - 9 的羅馬數字拿出來找規律:| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 空 | I | II | III | IV | V | VI | VII | VIII | IX |
- 0?~3? 就是 0 到 3 個?羅馬數字 ‘‘I’’ 表示
- 4 就是?5 - 1 但是減數放在了前面 既?“IV”
- 5 ~?8 就是用?一個 羅馬數字 “V”?加上 0 ~ 3?個 羅馬數字 “I” 來表示
- 9 就是 10 - 1 但是減數放在了前面 既?“IX”
| 0 | 1 | 2 | 3 | 4 |
| 空 | I | II | III | IV |
| 5 | 6 | 7 | 8 | 9 |
| V | VI | VII | VIII | IX |
余?0 ~ 3 的時候是:(“空” 或者 “V”?) 加上?余數個“I”
余 4 的時候是:“I” 加上一個 “X”
如:個位就是 I V X 三個羅馬數字,十位就是 X L D 三個羅馬數字, 以此類推。到目前為止我們已經發現了具體規律,我們來嘗試著編寫代碼:
/** * @param {number} num * @return {string} */var?intToRoman?=?function(num)?{ let result = [] let unit = ['I', 'V', 'X', 'L', 'C', 'D', 'M'] let index = 0 while(num){ let n = num % 10 let pre = n >= 5 ? unit[index + 1] : '' let u1 = unit[index] let u3 = unit[index + ((n >= 5) ? 2 : 1)] || '' switch (n % 5) { case 1: pre += u1 break case 2: pre += u1 + u1 break case 3: pre += u1 + u1 + u1 break case 4: pre = u1 + u3 break????????} result.push(pre) index += 2 num = Math.floor(num / 10) } return result.reverse().join('')};這道題目的具體代碼實現比較簡單,我這里就不逐行注釋了,有一個細節需要說明,就是我在處理每一位的時候是用的push()來存入結果數字,在返回答案是先reverse(),在進行數組元素連接成字符串。
原因就是對于同樣的結果操作,push() + reverse() 的操作 比 unshift() 操作快一些,這應該是js的引擎實現決定的,有更深入了解的同學歡迎留言去解釋一下~。
在leetcode上,為了更快的運行結果,還可以用一些預先計算并直接體現在代碼上,因為本題的要求是羅馬數字在1 ~ 3999的范圍,所以羅馬數字組合只有四種,可以直接列出來。我們看一下leetcode上這道題目前最快的代碼示例:
/** * @param {number} num * @return {string} */var intToRoman = function(num) { function TurnFive(n, one, five, ten){ if(n != 0){ if(n < 4){ return one.repeat(n); } if(n == 4){ return one + five; } if(n < 9){ let times = n-5; let I = one.repeat(times) return five + I; } if(n == 9){ return one + ten; } } return ""; } let than = Math.floor(num / 1000); let hon = Math.floor(num % 1000 / 100); let ten = Math.floor(num % 1000 % 100 /10); let ge = Math.floor(num % 1000 %100 % 10); return TurnFive(than, "M", "", "") + TurnFive(hon, "C", "D", "M") + TurnFive(ten, "X", "L", "C") + TurnFive(ge, "I", "V", "X");};這種針對具體題目的優化在一些online judge的比賽中很常見,不過它的擴展性就會弱一些, 比如 范圍要求是 1 ~3999999 那需要在代碼中直接列出來的內容就有點多了。所以還是發現規律,寫出更通用的代碼才是我們追求的。
這道題到這里就結束了,大家可以自己練練手,最后祝大家周末愉快,明天我會做一個《動態規劃解題的常見題集合》,不過只有一道題會從頭開始分析,剩下的題目只講解思路和特征,也算是給大家留一個聯系的機會,讓大家真是的練練手。
如果你覺得文章的內容能給你帶來收獲,歡迎關注?+?點贊在看?+?轉發,更期待你能推薦給身邊的小伙伴,讓我們一起來梳理前端知識!一起加油!「?往期回顧?」動態規劃(DP)解積雨問題
動態規劃(DP)解最大連續子序列文章涉及到源碼已經在github中開源
請在公眾號中發送“源碼”獲取代碼地址
讓我知道你在看
總結
以上是生活随笔為你收集整理的string 找出所有数字 index_发现规律,解决整数转罗马数字的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 新势力超跑鼻祖前途推新车:双门纯电小钢炮
- 下一篇: 石子合并问题java,石子合并问题 G