最近开始尝试在leecode网站上做一些较简单的算法题
目前底子比较薄,暂时还只能做一些简单的题目,这里记录了一个比较经典的题目:
罗马数字与整数的互相转换:
- 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
一开始看到题目百思不得其解,完全无从下手,后来还是看了评论区的答案才有了思路:
首先建立一个HashMap来映射符号和值,然后对字符串从左到右来,如果当前字符代表的值不小于其右边,就加上该值;否则就减去该值。以此类推到最左边的数,最终得到的结果即是答案
主要观察罗马数字的规律:4,9,40,90,400,900这几个数都要先累加再减
如果前一个字符是"I",后一个数字是"V",“X"那么累加的时候先累加在减二,如果前一个数字是"X”,后一个数字是"L"或者"C",就减20,如果前一个数字是"C",后一个数字是"D"或者"M",就减200;
- 代码如下
public static int romanToInt(String s) {
Map<Character, Integer> map = new HashMap<>();
map.put('I', 1);
map.put('V', 5);
map.put('X', 10);
map.put('L', 50);
map.put('C', 100);
map.put('D', 500);
map.put('M', 1000);
char[] arr = s.toCharArray();
int sum = 0;
for (int i = 0; i < arr.length; i++) {
if(i!=0){
if(arr[i-1]=='I'&&(arr[i] =='V'||arr[i]=='X')){
sum+=map.get(arr[i])-2;
}else if(arr[i-1]=='X'&&(arr[i]=='L'||arr[i]=='C')){
sum+=map.get(arr[i])-20;
}else if(arr[i-1]=='C'&&(arr[i]=='D'||arr[i]=='M')){
sum+=map.get(arr[i])-200;
}else{
sum+=map.get(arr[i]);
}
}else{
sum+=map.get(arr[0]);
}
}
return sum;
}
- 罗马数字转整数完成,现在要把整数转罗马数字(范围再3999内)
有了上一题的经验,这一题不像一开始那样一点思路都没有,我的想法是把数字拆成个十百千四个位数,然后按照0到9匹配罗马字符串,再累加
public static String intToRoman(int num) {
int qian = num/1000*1000;//获取千位
int bai = (num-qian)/100*100;//获取百位
int shi = (num-qian-bai)/10*10;//获取十位
int ge = num-qian-bai-shi;//获取各位
StringBuffer sb = new StringBuffer();
int [] nums = {3000,2000,1000,900,800,700,600,500,400,300,200,100,90,80,70,60,50,40,30,20,10,9,8,7,6,5,4,3,2,1};
String[] arrs = {"MMM","MM","M","CM","DCCC","DCC","DC","D","CD","CCC","CC","C","XC","LXXX","LXX","LX","L","XL","XXX","XX","X","IX","VIII","VII","VI","V","IV","III","II","I"};
for (int i = 0; i < nums.length; i++) {
if(qian==nums[i]){
sb.append(arrs[i]);
}
if(bai==nums[i]){
sb.append(arrs[i]);
}
if(shi==nums[i]){
sb.append(arrs[i]);
}
if(ge==nums[i]){
sb.append(arrs[i]);
}
}
return sb.toString();
}
最终虽然完成了需求,但是代码写得太痛苦,因为匹配的数组太长了,一开始疏漏很多情况,代码的可读性差,再参考了评论区答案后,得出了比较好的解答
public String intToRoman(int num) {
String s = "";
int [] nums = {1000,900,500,400,100,90,50,40,10,9,5,4,1};
String[] arrs = {"M", "CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
for (int i = 0; i < nums.length; i++) {
while(num>=nums[i]){
s+=arrs[i];
num-=nums[i];
}
}
return s;
}
这种方法,大大减少了代码量,性能提升也很明显,原先的程序要耗时80ms,现在只要56ms,看来写代码最重要的还是思路,这一点的提升任重而道远