LeetCode--13.罗马数字转整数

前引:其实我做完12题之后接着做这道题,我还是挺蒙的,看了眼难度,有点怀疑我的智商,但理清思路了之后,也不难,这两天有事情,就发布得少,今天是晚上打完英雄联盟躺在床上,惊醒,发现有好久没有发布了,不能再懒惰下去了,所以拖着疲惫的身体,写了一下吧

本次特点(如果某次题解,我觉得我特别棒,那我就会声明一下):

                发布了一个非主流的新方法,至少我在LeetCode上没见过,你如果跟我想的一样的话,那我得好好夸你了,好了,下面正式开始

解题思路:

        1.获取信息:(本来想直接略过的,因为我上一条博客在12题的时候已经解释得超级清楚了,但还是照顾你,写出来吧)

                (1)获得了基础的罗马数字转换表

                (2)从左往右读,左边的罗马字符对应的值小于右边的罗马字符的值

                                两者要一起看,值为右边的值减去左边的值

                                如:"IV","I"为1,"V"为5,"IV"为5 - 1 = 4

                (3)从左往右读,左边的罗马字符对应的值大于等于右边的罗马字符的值

                                就会出现两种情况,我给鲜明的例子

                                第一种情况,如:"III","I"为1,"III"为1 + 1 + 1 = 3

                                第一种情况,如:"VIII","V"为5,"I"为1,"VIII"为5 + 1 + 1 + 1 = 8

                (4)结果的大小在1到3999,闭区间

        2.分析问题:其实我获取信息的时候已经精炼过一次了,已经够易懂了,我这次就不再分析一次了,平时我的分析问题环节都是十分精彩的,这次例外,主要是特别简单,没有这个环节,我觉得差了点什么,就没有删掉

        3.示例查验:唯一给我的启发就是,让我知道了,从右往左读,比从左往右读简单,我觉得啊,平时我的示例查验环节也是十分精彩的

        4.尝试编写代码(重要环节来临

                我想出来两种方法,其中一种,我觉得特别妙

                (1)暴力法

                        由之前的示例启发,我觉得从右往左读要简单一点,每个人的想法不一样,有人觉得从左往右比较简单,所以,” 每个人眼里的代码都是不一样的,希望你可以找到属于自己的代码 “

                        通过基础的罗马数字转换表,它可以根据我在获取信息环节时总结出来的两种情况来获得答案,代码如下

class Solution {
public:
    int romanToInt(string s) {
        int res=0;
        unordered_map<char,short>Roma{
            {'I',1},{'V',5},{'X',10},{'L',50},{'C',100},{'D',500},{'M',1000}
        };//基础罗马数字转换表
        for(int i=s.size()-1;i>=0;i--){//从右往左遍历
            if(i>0&&(Roma[s[i]]>Roma[s[i-1]])){//如果左边的罗马符号的值小于右边罗马符号的值
                res=res+(Roma[s[i]]-Roma[s[i-1]]);
                i--;
                continue;
            }
            res+=Roma[s[i]];//如果左边罗马符号的值大于等于右边罗马符号的值
        }
        return res;
    }
};

                  (2)乱匹风锤法

                        滑动窗口法和动态规划,它们的思想给了我启发

                        思路:我们知道,最多有四个字符作为一个整体来转换成一个整数,我给鲜明的例子

                        如:"VIII",这四个字符表示8,对吧

                        那么我们将字符的所有合法的组合形式都写出来存在容器种,然后,第一次取,我们取四个字符组成字符串去容器种查找

                        如果查到了,那就直接加上,如果没查到,那就取三个字符,再次查找

                        我们有保底机制,那就是当取一个字符时,肯定能查找到,所以,我叫它乱匹风锤法,致敬一下糖加三勺

class Solution {
public:
    int romanToInt(string s) {
        int res = 0;
        unordered_map<string, int>Roma{
            {"I",1},{"II",2},{"III",3},{"IV",4},{"V",5},{"VI",6},{"VII",7},{"VIII",8},{"IX",9},{"X",10},{"XX",20},{"XXX",30},{"XL",40},{"L",50},{"LX",60},{"LXX",70},{"LXXX",80},{"XC",90},{"C",100},{"CC",200},{"CCC",300},{"CD",400},{"D",500},{"DC",600},{"DCC",700},{"DCCC",800},{"CM",900},{"M",1000},{"MM",2000},{"MMM",3000}
        };//将罗马字符的所有组合情况写入容器种
        int size = s.size();//取s的大小
        int i=0;//取字符的起点
        while(i<=size-1){
            res+=OP(s,Roma,i);
        }
         return res;
    }
private:
    int OP(string&s,unordered_map<string,int>&Roma,int& i){//注意,这里i用的是引用,这里改变i,i会整体改变的
        int cap=4;//取字符的个数,每次都改变的
        int res=0;
        while(cap){
            string tool=s.substr(i,cap);//用来存,取得的字符组合而成的字符串,所以叫他工具人(tool)
            if(Roma.find(tool)!=Roma.end()){//如果查找到了,就直接加上,break,不用再继续循环了
                res+=Roma[tool];
                break;
            }
            cap--;//没找到就减少取字符的数目
        }
        i+=cap;//取得了之后,就移动i到合适的位置
        return res;
    }
};

                (3)四指针法:我就不写了,大概思路跟乱匹风锤法异曲同工,但是没有前者简练,比较不推荐

                最后:今天是疲惫了,这次比较偷懒,没有写得很详细,脸上无光,祝早睡

还是要提一嘴,纸上得来终觉浅,绝知此事要躬行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值