这道题看了半年但是一直没敢做,因为我连罗马数字具体是什么都不明白。。。
基本概念:
“罗马数字共有七个,即I(1),V(5),X(10),L(50),C(100),D(500),M(1000)。按照下面的规则可以表示任意正整数。
重复数次:一个罗马数字重复几次,就表示这个数的几倍。
右加左减:在一个较大的罗马数字的右边记上一个较小的罗马数字,表示大数字加小数字。在一个较大的数字的左边记上一个较小的罗马数字,表示大数字减小数字。但是,左减不能跨越等级。比如,99不可以用IC表示,用XCIX表示。
加线乘千:在一个罗马数字的上方加上一条横线或者在右下方写M,表示将这个数字乘以1000,即是原数的1000倍。同理,如果上方有两条横线,即是原数的1000000倍。
单位限制:同样单位只能出现3次,如40不能表示为XXXX,而要表示为XL。”
“左减不能跨越等级。比如,99不可以用IC表示,用XCIX表示。”是一开始让我比较困惑的。。等级是什么意思?turns out, 比较大的罗马字符只能放在左边。
“单位限制:同样单位只能出现3次,如40不能表示为XXXX,而要表示为XL。” 也是一个让我不太知道如何达成的点。我做的时候一直在想难道要检查是否在一个位置已经出现了3次? 然而, by nature, 罗马数字的这13个symbol之间的间隔就注定了不可能有数字相差超过3倍于这个数。
比如10和40, 差了30,正好3倍。
这13个 symbol的选择至关重要。 题目:Input is guaranteed to be within the range from 1 to 3999.
int[] values = {1000,900,500,400,100,90,50,40,10,9,5,4,1};
String[] strs = {"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
Basic idea:
把target的数字和values array里的数字从大到小一个个比较。碰到第一个比自己小的数字,num = num - 那个数字。 然后能减几次减几次直到比它小
比如说我现在有30这个数字, 30 比40小, 无视40. 30比10大,好,先减去10。 现在num 变成了20, 还是比10大,那再减去10, =10, 还是没10小,再减一次。 一共减了3次,相应的append 3个10的对应罗马数字 X. so XXX.
9月9: 我特么服了。。。。。。。大神一行搞定。只要4个bucket 因为罗马数字最多4999