LeetCode 12 Int2Roman && 13 Roman2Int
2015-08-01 00:23
253 查看
1.Integer to Roman
Given an integer, convert it to a roman numeral.
Input is guaranteed to be within the range from 1 to 3999.
解题思路:
首先,要搞清楚罗马数字命名规则,搞清规则之后下手,就非常容易。
3999以内的罗马数字主要由几个单字组成,I 、V、 X、 L、C、M。一般情况下,都是大的单字后面跟着小的单字,如VI VII 等,但是一旦小的单字在前面就表示减法,如IV(4)、CM(900)等等。为什么有减法规则?因为罗马数字命名规则要求单字不能重复出现超过3次。因此,有了减法规则。因此在构造罗马数字的时候,应该考虑所有会出现的单字以及减法单字。
3999以内的单字以及减法字如下:(两个数组,以索引映射)
int val[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
String re[] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
借组上述规定,按照递减的办法将阿拉伯数减去上述的基数,每次递减字符串自加一个对应的罗马基数。直到阿拉伯数递减结果为0,则构造出罗马字。代码复杂度为O(n),实际上接近O(n^2),因为重置了i。
代码如下:C语言版,这个代码段让我复习了c语言的内存知识,之前没有用malloc分配内存(分配到堆上),而是直接定义在了函数栈空间当中,计算不能得到结果。
Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
有了第一题的铺垫,这一题简单了许多,为了提高效率,利用map直接映射单字和阿拉伯数组的索引,当然要考虑双字符以及单字符的影响,对其进行判断。这里用了个map很cool的初始化方法,看上去非常舒服。
代码如下:
实际上,上述算法因为是在java的情况下,没有发挥最好的性能,实际上利用c的char有着更好地性能,这里有个简洁的算法只考虑上述加减法的逻辑,当时我怎么没想到,掉到java封装的坑里了。
Given an integer, convert it to a roman numeral.
Input is guaranteed to be within the range from 1 to 3999.
解题思路:
首先,要搞清楚罗马数字命名规则,搞清规则之后下手,就非常容易。
3999以内的罗马数字主要由几个单字组成,I 、V、 X、 L、C、M。一般情况下,都是大的单字后面跟着小的单字,如VI VII 等,但是一旦小的单字在前面就表示减法,如IV(4)、CM(900)等等。为什么有减法规则?因为罗马数字命名规则要求单字不能重复出现超过3次。因此,有了减法规则。因此在构造罗马数字的时候,应该考虑所有会出现的单字以及减法单字。
3999以内的单字以及减法字如下:(两个数组,以索引映射)
int val[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
String re[] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
借组上述规定,按照递减的办法将阿拉伯数减去上述的基数,每次递减字符串自加一个对应的罗马基数。直到阿拉伯数递减结果为0,则构造出罗马字。代码复杂度为O(n),实际上接近O(n^2),因为重置了i。
代码如下:C语言版,这个代码段让我复习了c语言的内存知识,之前没有用malloc分配内存(分配到堆上),而是直接定义在了函数栈空间当中,计算不能得到结果。
char* intToRoman(int num) { unsigned int val[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 }; char* r[] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" }; char *re = NULL; re=(char*)malloc(sizeof(char*) * 20); if (num > 3999 || num < 0) return re; int i = 0; while (num>0) { if (num>=val[i]) { strcat(re, r[i]); num -= val[i]; i = 0; continue; } i++; } return re; }java版如下:相比于c语言的char数组,java的string就方便了许多。
public String intToRoman(int num) { int val[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 }; String r[] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" }; String re=""; if (num > 3999 || num < 0) return re; int i = 0; while (num>0) { if (num>=val[i]) { re+=r[i]; num -= val[i]; i = 0; continue; } i++; } return re; }
2.Roman to Integer
Given a roman numeral, convert it to an integer.Input is guaranteed to be within the range from 1 to 3999.
有了第一题的铺垫,这一题简单了许多,为了提高效率,利用map直接映射单字和阿拉伯数组的索引,当然要考虑双字符以及单字符的影响,对其进行判断。这里用了个map很cool的初始化方法,看上去非常舒服。
代码如下:
public int romanToInt(String s) { int val[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 }; String re[] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" }; HashMap<String,Integer> hm = new HashMap<String,Integer>(){ { put("M", 1000); put("CM", 900); put("D", 500); put("CD", 400); put("C", 100); put("XC", 90); put("L", 50); put("XL", 40); put("X", 10); put("IX", 9); put("V", 5); put("IV", 4); put("I", 1); } }; int n = s.length(); int i = 0; int result=0; while (i != n){ if(i<n-1){ String t = s.substring(i, i+2); if(hm.get(s.substring(i, i+2))!=null){ result+=hm.get(t); i+=2; continue; } } if(hm.get(s.substring(i,i+1))!=null){ result+=hm.get(s.substring(i,i+1)); } i++; } return result; }
实际上,上述算法因为是在java的情况下,没有发挥最好的性能,实际上利用c的char有着更好地性能,这里有个简洁的算法只考虑上述加减法的逻辑,当时我怎么没想到,掉到java封装的坑里了。
#define I 1 #define V 5 #define X 10 #define L 50 #define C 100 #define D 500 #define M 1000 int romanToInt(char* s) { char pre = 'A'; char current = 'A'; int amount = 0; for (int i = strlen(s) - 1; i >= 0; i--) { current = toupper(s[i]); if (s[i] == 'I') { if (pre == 'V' || pre == 'X') { amount -= I; } else { amount += I; } } if (s[i] == 'V') { amount += V; } if (s[i] == 'X') { if (pre == 'L' || pre == 'C') { amount -= X; } else { amount += X; } } if (s[i] == 'L') { amount += L; } if (s[i] == 'C') { if (pre == 'D' || pre == 'M') { amount -= C; } else { amount += C; } } if (s[i] == 'D') { amount += D; } if (s[i] == 'M') { amount += M; } pre = current; } return amount; }
相关文章推荐
- mysql异常Packet for query is too large(mysql写入数据过大)
- HDU 4883--TIANKENG’s restaurant【区间覆盖 && 暴力】
- python笔记之编程风格大比拼
- Ubuntu 12.04 LTS安装Windows字体
- C语言的图形函数笔记
- dom4j创建xml
- 查找算法
- 【黑马程序员】C语言之函数
- HDU - 4396 More lumber is required (BFS 最短路)
- fedora 20升级至22 无线网卡失效 解决办法
- 赢了!北京获2022年冬奥会举办权
- bzoj1005【hnoi2008】明明的烦恼
- 对于 For 循环的新认识
- nyoj14 会场安排问题
- Volley和xUtils取cookie的实现
- CodeForces - 448D—Multiplication Table--二分法(nlogn)
- 对象池
- 解决ViewPager和PagerAdapter中调用notifyDataSetChanged失效的问题
- Zabbix 的 MySQL 监控客户端配置
- ios开发之给Xcode安装颜色主题及自动注释插件