首页 > 其他分享 >【LeetCode刷题记录】简单篇-13-罗马数字转整数

【LeetCode刷题记录】简单篇-13-罗马数字转整数

时间:2024-04-05 22:30:14浏览次数:25  
标签:字符 13 int sum 罗马数字 romanToInt include LeetCode 刷题

【题目描述】 

罗马数字包含以下七种字符: I, V, X, LCD 和 M

字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

例如, 罗马数字 2 写做 II ,即为两个并列的 1 。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

  • I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
  • X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 
  • C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。

给定一个罗马数字,将其转换成整数。


【测试用例】

示例1:

        输入:s="III"

        输出:3

示例2:

        输入:s="IV"

        输出:4

示例3:

        输入:s="IX"

        输出:9

示例4:

        输入:s="LVIII"

        输出:58

        解释:L=50,V=5,III=3

示例5:

        输入:s="MCMXCIV"

        输出:1994

        解释:M=1000,CM=900,XC=90,IV=4


【思路分析】

我的解法很简单也很暴力,用sum存储结果,一个for循环依次遍历字符串,'I','X','C'三个字符做特殊处理(对应罗马数字的六种特殊情况):

如果当前字符是'I',看下一个字符是不是'V'或者'X',是'V'的话sum+=4,是'X'的话sum+=9;

如果当前字符是'X',看下一个字符是不是'L'或者'C',是'L'的话sum+=40,是'C'的话sum+=90;

如果当前字符是'C',看下一个字符是不是'D'或者'M',是'D'的话sum+=400,是'M'的话sum+=900;

其余情况按照罗马数字与整数的对应值直接加到sum就好。


【参考代码】

C和C++实现核心逻辑是一样的,不同的只是语法差异,之所以写两种只是为了练习两种语言的语法而已。

C语言实现

#include <stdio.h>
#include <string.h>

//easy-13-罗马数字转整数 
int romanToInt(char* s);
int charToInt(char c);

int main(){
	char s[15];
	scanf("%s", s);
	int res = romanToInt(s);
	printf("%d\n", res);
	return 0;
}

int romanToInt(char* s){
	int i,sum=0;
	for(i=0;i<strlen(s);i++){
		if(s[i]=='I'){
			if(s[i+1]=='V'){
				sum+=4;
				i++;
			}else if(s[i+1]=='X'){
				sum+=9;
				i++;
			}else{
				sum+=1;
			}
		}else if(s[i]=='X'){
			if(s[i+1]=='L'){
				sum+=40;
				i++;
			}else if(s[i+1]=='C'){
				sum+=90;
				i++;
			}else{
				sum+=10;
			}
		}else if(s[i]=='C'){
			if(s[i+1]=='D'){
				sum+=400;
				i++;
			}else if(s[i+1]=='M'){
				sum+=900;
				i++;
			}else{
				sum+=100;
			}
		}else{
			sum = sum + charToInt(s[i]);
		}
	}
	return sum;
}

int charToInt(char c){
	switch(c){
		case 'I': return 1;
		case 'V': return 5;
		case 'X': return 10;
		case 'L': return 50;
		case 'C': return 100;
		case 'D': return 500;
		case 'M': return 1000;
	}
	return 0;
}

C++实现

#include <iostream>
#include <string>
using namespace std;

//easy-13-罗马数字转整数 
class Solution {
	public:
	    int romanToInt(string s);
	    int charToInt(char c);
};

int Solution::romanToInt(string s){
	int i,sum=0;
	for(i=0;i<s.length();i++){
		if(s[i]=='I'){
			if(s[i+1]=='V'){
				sum+=4;
				i++;
			}else if(s[i+1]=='X'){
				sum+=9;
				i++;
			}else{
				sum+=1;
			}
		}else if(s[i]=='X'){
			if(s[i+1]=='L'){
				sum+=40;
				i++;
			}else if(s[i+1]=='C'){
				sum+=90;
				i++;
			}else{
				sum+=10;
			}
		}else if(s[i]=='C'){
			if(s[i+1]=='D'){
				sum+=400;
				i++;
			}else if(s[i+1]=='M'){
				sum+=900;
				i++;
			}else{
				sum+=100;
			}
		}else{
			sum = sum + charToInt(s[i]);
		}
	}
	return sum;
}

int Solution::charToInt(char c){
	switch(c){
		case 'I': return 1;
		case 'V': return 5;
		case 'X': return 10;
		case 'L': return 50;
		case 'C': return 100;
		case 'D': return 500;
		case 'M': return 1000;
	}
	return 0;
}

int main(){
	Solution sol;
	string str;
	cin>>str;
	int res = sol.romanToInt(str);
	cout<<res<<endl;
	return 0;
}

【题解思路】

我每写完一道题都会去看评论大神们的题解,受益匪浅。本题还可以使用哈希法。

在观察罗马数字的规律之后可以发现,一般情况下,罗马数字中任意两个数中左边的数大于等于右边的数,例如:"LVIII",L>V>I;而在六种特殊情况中,左边的数小于右边的数,例如:"MCMXCIV",其中"CM"和"XC"是特殊情况,CM=1000-100=900,也可以理解为-100+1000,"XC"也是同样的道理。

按照上述说法,核心逻辑就可以归纳为:当当前罗马数字小于下一个罗马数字时,减去当前罗马数字对应的整数值,反之则加上当前罗马数字对应的整数值。

使用哈希的方法来存储 {罗马数字:整数值},在C++中用map容器实现。

我的暴力方法和题解的方法对时空复杂度的影响不是很大,但是题解的方法提供了一种思路:类似于这种两个值一一对应的情况都可以考虑哈希。


【参考代码】

#include <iostream>
#include <string>
#include <map>
using namespace std;

//easy-13-罗马数字转整数 
class Solution {
	public:
	    int romanToInt(string s);
};

int Solution::romanToInt(string s){
	int res=0;
	map<char,int> map_roman={
		{'I',1},
		{'V',5},
		{'X',10},
		{'L',50},
		{'C',100},
		{'D',500},
		{'M',1000}
	};
	int i;
	for(i=0;i<s.length();i++){
		if(map_roman[s[i]] < map_roman[s[i+1]]){
			res -= map_roman[s[i]];
		}else{
			res += map_roman[s[i]];
		}
	}
	return res;
} 

int main(){
	Solution sol;
	string str;
	cin>>str;
	int res = sol.romanToInt(str);
	cout<<res<<endl;
	return 0;
}

标签:字符,13,int,sum,罗马数字,romanToInt,include,LeetCode,刷题
From: https://blog.csdn.net/Ren_Ht/article/details/137397676

相关文章

  • mysql 报错 ERROR 1396 (HY000): Operation ALTER USER failed for root@localhost 解
    mysql修改密码ALTERUSER‘root’@‘localhost’IDENTIFIEDBY‘123’;时,报错ERROR1396(HY000):OperationALTERUSERfailedforroot@localhost解决方案:2024-4-3段子手1681、首先连接权限数据库:mysql>usemysql;2、查看user主机名:mysql>selectuse......
  • Leetcode 无重复字符的最长子串
    powcai的滑动窗口解决问题:不断向后滑动窗口,出现重复元素,重新计算窗口,巧妙利用map来记录先前出现的元素的位置索引classSolution{publicintlengthOfLongestSubstring(Strings){//滑动窗口解决该问题intleft=0;intmax=0;Map......
  • Leetcode 412. Fizz Buzz
    给你一个整数n,找出从1到n各个整数的FizzBuzz表示,并用字符串数组answer(下标从1开始)返回结果,其中:answer[i]==“FizzBuzz”如果i同时是3和5的倍数。answer[i]==“Fizz”如果i是3的倍数。answer[i]==“Buzz”如果i是5的倍数。answer[i]......
  • LeetCode in Python 300. Longest Increasing Subsequence (最长递增子序列)
    求最长递增子序列是深度优先搜索(DFS)的一种应用,有两种比较好的方法可以解决。第一种是动态规划法,时间复杂度为O(n*n),即设置边界条件和更新迭代公式求解最优解。第二种使用二分查找将时间复杂度降为O(nlogn)。本文给出两种方法的实现代码及说明。示例:图1最长递增子序列输入......
  • LeetCode 13. 罗马数字转整数
    解题思路通过样例我们可以知道,将目标对应值和下一个目标对应值进行比较,如果小于,则sum=sum+目标对应值,如果大于,则sum=sum-目标对应值。最终的sum就是正确答案。相关代码classSolution{public:intromanToInt(strings){unordered_map<char,int>a;......
  • 《架构风清扬-Java面试系列第13讲》说一说Java对象在内存中的生命周期
    大家好,加个餐!像线程的生命周期,Servlet的生命周期,相信这类问题大家都非常熟悉了Java对象在内存中的生命周期,这个题目倒是有些新鲜来,思考片刻,说出你的答案(PS:上图缓冲)Java对象在其内存中的生命周期可以被划分为多个阶段,下面钊哥逐个给大家说一说1,创建阶段(Creation......
  • LeetCode-142. 环形链表 II【哈希表 链表 双指针】
    LeetCode-142.环形链表II【哈希表链表双指针】题目描述:解题思路一:快慢指针判断是否有环见解题思路二:set()解题思路三:0题目描述:给定一个链表的头节点head,返回链表开始入环的第一个节点。如果链表无环,则返回null。如果链表中有某个节点,可以通过连续跟踪next......
  • LeetCode 704.二分查找
    一、题目二、解题注:本文均是Java代码1、双闭区间写法classSolution{publicintsearch(int[]nums,inttarget){intleft=0,right=nums.length-1;while(left<=right){intmiddle=(left+right)>>>1;......
  • lanqiao OJ 3513 岛屿个数(2023省赛)
    原题链接:3.岛屿个数-蓝桥云课(lanqiao.cn)感觉这个题出的真的特别好,考察了对bfs的使用,包括连通性的一系列判断,如果对bfs掌握的不熟练真的很难想出如何下手来做这道题。这里我们需要用海水来进行bfs,海水可以渗透,也就是说可以走8个方向,因为我们要从任意一个边界点出发,所以我......
  • LeetCode 1539. Kth Missing Positive Number
    原题链接在这里:https://leetcode.com/problems/kth-missing-positive-number/description/题目:Givenanarray arr ofpositiveintegerssortedina strictlyincreasingorder,andaninteger k.Return the kth positive integerthatis missing fromthisarra......