zoukankan      html  css  js  c++  java
  • LeetCode Notes_#13 Roman to Integer

    LeetCode Notes_#13 Roman to Integer

    Contents

    Problem

    Roman numerals are represented by seven different symbols: I, V, X, L, C, D 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.

    Solution

    思路

    这是一个字符串处理的问题,从左到右的去“识别”每部分代表的数字是多少,然后把他们加起来。

    1. 字符串划分

    如何“识别”?有时候是一个字母代表一个数字,有时候是两个字母代表一个数字;
    什么时候把一位字母看做一个数字?什么时候把两位字母看做一个数字呢?
    两个字母当成一个数字只有下边的几种情况:

    IV=4 IX=9
    XL=40 XC=90
    CD=400 CM=900

    所以从前往后去获取字符串的每一个字母,如果遇到I,X,C,就要特别地判断一下,他们和后边的字母连在一起是否组成一个数字?如果是,那么直接读取两位字母。
    而对于其他的几个字母V,L,D,M,就肯定是单独代表一个数字,不需要管后边是什么,直接读取一位数字。

    2. 字母转化成数字

    识别出代表数字的一个或者两个字母之后,如何转换为数字呢?我想到了dict,总共只有6(双字母)+7(单字母)=13种组合
    将字符串作为key,对应的数字作为value建立dict,然后就可以用达成字符串转化为数字的目的了

    代码

    class Solution(object):
        def romanToInt(self, s):
            """
            :type s: str
            :rtype: int
            """
            d={'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000,'IV':4,'IX':9,'XL':40,'XC':90,'CD':400,'CM':900}
            special='IXC'#特殊对待的几个
            num=0
            i=0
            #for i in range(len(s)-1):
            if len(s)>1:
                while i<len(s)-1:
                    if s[i] in special:#几个特殊前缀
                        if s[i]+s[i+1] in d:#加上后一位看是否是数字
                            num=num+d[s[i]+s[i+1]]#如果是,就加上
                            i=i+2#跳过下一轮循环
                        else:
                            num=num+d[s[i]]
                            i=i+1
                    else:
                        num=num+d[s[i]]
                        i=i+1
                if s[-2]+s[-1] not in d:
                    num+=d[s[-1]]
                return num
            else: 
                return d[s]
    

    time:108ms,faster than 37%

    记录一下几个开始被我忽视的问题

    1. 如何跳过一轮循环?
      在for循环中,是不可以改变循环变量的值的,我想达到的目的是,检测出两个字母的情况,直接跳过下一轮循环,我直接写了i=i+1,然而这是没有用的,所以改成了while循环,并且在每一个分支修改循环变量
    2. 越界问题
      几次遇到字符串越界问题:
    • 循环终止条件要想好,注意range(i)是从0数i个,[0,i-1],这种不会越界;
    • 但是用while遍历整个对象的话,应该写成while(i<len(s)),由于我使用了s[i+1],所以必须刨去最后一个元素才不会越界,所以是while(i<len(s)-1)
      那么最后一个字母就需要单独去处理
    • 衍生的问题
      如果最后一个数字就是两位字母表示的,那么会第二个字母会被当成独立的多加一个
    1. 另一个要考虑的情况:
    • 只有一个字符:‘D’,因为后面用到s[-2].也会报越界的错
      解决方法就是一开始就要考虑单个字符的情况
    1. 一个小tip:可以用负数角标来倒着访问可迭代对象

    另一个很好的思路

    高票答案

    class Solution:
    # @param {string} s
    # @return {integer}
    def romanToInt(self, s):
        roman = {'M': 1000,'D': 500 ,'C': 100,'L': 50,'X': 10,'V': 5,'I': 1}
        z = 0
        for i in range(0, len(s) - 1):
            if roman[s[i]] < roman[s[i+1]]:
                z -= roman[s[i]]
            else:
                z += roman[s[i]]
        return z + roman[s[-1]]
    

    没有去判断一个字母还是两个字母,他找到了一个规律,如果后一个字母大于前一个字母,那么直接用后一个字母减去前一个字母即可。相当于只是判断每个字母的符号是加还是减就可以了(最后一个字母总是加)
    这就减少了很多判断的逻辑。很棒。

  • 相关阅读:
    wifite+aimon-ng
    DC-2
    chrome插件开发
    mongoose的基本操作方法
    webpack中的require.context
    sequelize 数据类型 model
    React17 系统精讲 结合TS打造旅游电商平台
    2021必修 React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目
    21.8.2
    胡渊鸣《浅析信息学竞赛中概率论的基础与应用》学习笔记
  • 原文地址:https://www.cnblogs.com/Howfars/p/9745224.html
Copyright © 2011-2022 走看看