leetcode 13. Roman to Integer 解法 python3

一.问题描述

Roman numerals are represented by seven different symbols: IVXLCD and M.

Symbol       Value
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II.

Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:

  • I can be placed before V (5) and X (10) to make 4 and 9. 
  • X can be placed before L (50) and C (100) to make 40 and 90. 
  • C can be placed before D (500) and M (1000) to make 400 and 900.

Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999.

Example 1:

Input: "III"
Output: 3

Example 2:

Input: "IV"
Output: 4

Example 3:

Input: "IX"
Output: 9

Example 4:

Input: "LVIII"
Output: 58
Explanation: L = 50, V= 5, III = 3.

Example 5:

Input: "MCMXCIV"
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.

二.解题思路

方法1:

罗马数字一般来说都是左边的比右边的大。

例外的6个情况已经列出来。

我们直接遍历数组,判断s[i]代表的数字是否大于s[i-1],不是的话直接累加,是的话要把s[i-1]代表的值从累加的结果中减去不且还要再减一次,然后再加上s[i]。

时间复杂度:O(N),空间复杂度:O(1)

我们只需要跟踪前后2个数的状态就行了,因为不存在s[i-1]s[i+2](1)或者s[i-1]s[i]>s[i-1]s[i],因此应该在s[i-1]左边因为他大。同理情况2。

方法2:

你也可以直接计算 I, X等和6个特例情况罗马字符在数组中的出现次数,然后求和。注意以下单独元素和特定元素有重复元素情况下计算单个元素的个数。比如I 和 IV, IV中的I在计数时也算在I里了,所以计算I次数的时候要减掉IV中的I,这方法比上面慢。

方法3:

把6个特殊情况单独拿出来处理,相加完后在字符串中替换掉,剩下的字符串就是没有特殊情况的罗马数字,直接加。

当然也会比较慢。

更多leetcode算法题解法: 专栏 leetcode算法从零到结束

三.源码

方法1:

class Solution:
    def romanToInt(self, s: str) -> int:
        rom2num={'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}
        res=rom2num[s[0]]
        for i in range(1,len(s)):
            res+=rom2num[s[i]]-2*rom2num[s[i-1]] if rom2num[s[i]]>rom2num[s[i-1]] else rom2num[s[i]]
        return res

方法2:https://leetcode.com/problems/roman-to-integer/discuss/422150/Python-One-Liner

方法3:https://leetcode.com/problems/roman-to-integer/discuss/423025/python-3-solution

你可能感兴趣的:(leetcode算法从零到结束)