🤚我的博客
- 欢迎光临我的博客:
https://blog.csdn.net/qq_52434217?type=blog
🥛前言
记录一下一个中等题目的解题思路。
整型转罗马数字
题目
罗马数字包含以下七种字符: I
, V
, X
, L
,C
,D
和 M
。
字符 | I | V | X | L | C | D | M |
---|---|---|---|---|---|---|---|
数值 | 1 | 5 | 10 | 50 | 100 | 500 | 1000 |
特殊的:
I
可以放在V
(5) 和X
(10) 的左边,来表示 4 和 9。X
可以放在L
(50) 和C
(100) 的左边,来表示 40 和 90。C
可以放在D
(500) 和M
(1000) 的左边,来表示 400 和 900。
现在给你一个整数num
,将其转为罗马数字。其中1<=num<=3999
;
思路
考虑到这个题的数字最大为3999,可以不用考虑通用的算法。那么我们需要知道如何添加数值对应的字符串。
官网给出的题目有
示例 1:
输入: num = 3
输出: “III”
示例 2:
输入: num = 4
输出: “IV”
示例 3:
输入: num = 9
输出: “IX”
示例 4:
输入: num = 58
输出: “LVIII”
解释: L = 50, V = 5, III = 3.
示例 5:
输入: num = 1994
输出: “MCMXCIV”
解释: M = 1000, CM = 900, XC = 90, IV = 4.
我们可以从一个比较小的数考虑。以3为例,3由三个1组成,也就是III
。
但是4并不是由4个1组成,而是5-1
。那么当num >= 4
时就需要添加一个IV
。
是不是对这个结论很疑惑?其实具体来说只有num = 4
的时候才需要添加一个IV
。那么当num > 4
之后则是num >= 5
的情况了。由官方给出的例子58
可以看出,当num >= 5
时,由一个5个num-5
个1组成,在例子中也就是VIII
。
前面说过这里的III
是num-5
得到的,那么这个III
如何计算呢。其实只需要计算3个1就行了。这里就回到了前面的问题。
看到这里,应该有些许眉目了。假设num >= 5
。则可以通过num = num-5
的操作使num
的值缩小到num >= 0
。同时如果num < 4
的时候,可以多次num = num - 1
操作使num
减少到0
。
同理,特殊情况num >= 9
也需要考虑。
上面的过程用代码表示就是
res = ""
if num >= 9:
res += "IX"
if num >= 5:
num -= 5;
res += "V"
if num >= 4:
num -= 4
res += "IV"
if num >= 1:
num -= 1
res +="I"
再考虑到这题的数最大只有3999,那么我们可以将全部的特殊情况都枚举出来保存到两个数组中
values = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
romans = ["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"]
这样在进行判断的时候可以直接取出对应的数和值进行操作。
到这里后,关键点就在于如何实现循环。
这里肯定需要判断num
与values
中数的大小,然后进行相减和拼接操作。同时其中一个值可能会操作多次,比如num=3
时会执行三次操作。所以在这里使用while
循环更方便。
同时num
肯定一开始需要与最大的数进行比较,那么怎么移动到下一个数字进行比较也需要考虑。这里我们直接基于上面的判断条件进行操作。以num=7
为例,这里先判断num >= 4
成立,然后执行num -= 4
操作。随后再判断num >= 1
再进行操作。那么也就是指针先指向values[-2]
,然后指针指向values[-1]
。所以只要不满足条件,指针加一操作即可。同时这些操作的前提是num > 0
。那么过程就如下所示。
while num > 0:
# 只要大于某一个数
while num > values[i]:
num -= values[i]
res += romans[i]
# 否则
i++
解答
结合上面的推演过程,现在给出完整解答过程。
class Solution {
public String intToRoman(int num) {
int[] values = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
String[] romans = {"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
StringBuilder res = new StringBuilder();
int index = 0;
while(index< values.length){
while(num >= values[index]){
res.append(romans[index]);
num -= values[index];
}
index++;
}
return res.toString();
}
}
💠END
这个题不难,但是在代码的实现上写得比较仔细。毕竟我的目的就是为了能够强化思路转化代码的能力。
感叹时间过得太快了,计划赶不上变化。也可能是以前的变化不合理导致的,没有抓住问题关键,一直抓瞎。
为了找工作,现在只能放弃项目去专心刷题了。
一起加油!🆙🆙🆙
🏕️公众号
欢迎关注小夜的公众号,一个立志什么都能会的研究生。有不懂的地方请留言踢我!