LeetCode 12 - 罗马数字 - 解题思路记录 - GoLang

1,155 阅读3分钟

今天来看一下一道比较简单的leetcode题,第12题,数字转换的问题
我们先看题目

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:\

  1. I can be placed before V (5) and X (10) to make 4 and 9.
  2. X can be placed before L (50) and C (100) to make 40 and 90.
  3. C can be placed before D (500) and M (1000) to make 400 and 900.

这就是原文的题目,我们来看个官方例子:
Example1

Input: 3
Output: "III"

Example2

Input: 4
Output: "IV"

Example3

Input: 9
Output: "IX"

简单来说呢就是罗马数字中的4和9 是由IV 和 IX 组成相当于5-1和10-1
以此类推到40(XL),90(XC),400(CD),900(CM)都是由5跟10的倍数做减法出来的
说到这里的小伙伴有心里面有没有思路呢?
我刚看到这道题的时候,也在想需不需要各种用到什么复杂的数据结构,复杂的算法呢?
后来找了一些资料,我发现这道题有一个比较简单易懂的做法,那就是直接比较
我们来先看一下代码

func intToRoman(num int) string {
 one := []string{"","I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"} //1,2,3,4,5,6,7,8,9
 ten := []string{"","X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"} //10,20,30,40,50,60,70,80,90
 hundred := []string{"","C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"} //100,200,300,400,500,600,700,800,900
 thousand := []string{"","M", "MM", "MMM"}//1000,2000,3000
 if num < 10 {
  return one[num]
 }else if num >= 10 && num <= 99 {
  t := num / 10
  o := num % 10
  return ten[t] + one[o]
 }else if num >= 100 && num <= 999{
  h := num / 100
  t := num / 10 % 10
  o := num % 10
  return hundred[h] + ten[t] + one[o]
 }else {
  th := num / 1000
  h := num / 100 % 10
  t := num / 10 % 10
  o := num % 10
  return thousand[th] + hundred[h] + ten[t] + one[o]
 }
}

代码很简单,没有复杂的的for循环,也没有难懂的地方,非常简洁就能完成,但是我们也稍微讲解一下这个思路吧
首先是映射字符串的对照表

在这里定义了个,十,百,千的单位转换表
这里2个重点。

第二点 对数字取余的知识,我们来算一下 如果一个数字大于1000那么怎么取这个数字的千位呢?
是不是知道做法了,简单的数学题 nums/1000 就获得了千位
nums / 100 % 10获得百位
nums / 10 % 10获得十位
nums % 10获得个位
有了这个知识,其实大家可以不必要像我一样,在上面做4个判断,应该有一个更快捷的返回字符串的方法, 那这个方法就交给你们咯。
并且还有空间也能省下某个字符串,也交给你们优化了\