[算法刷题打卡]Day9

1、Leetcode-面试经典150题目17-13. 罗马数字转整数

思路:

1.我的做法很暴力,就是先用map将几个罗马数字存储一下

2.逐个遍历输入的字符串,对于I  X  C放在比他大的数字左边时特殊处理一下,其他的就是直接转换结果。

class Solution {
public:
    int romanToInt(string s) {
        unordered_map<char, int> RM;
        vector<char> ss(s.begin(), s.end());
        int ans = 0;
        int cv;
        // 初始化
        RM['I'] = 1;
        RM['V'] = 5;
        RM['X'] = 10;
        RM['L'] = 50;
        RM['C'] = 100;
        RM['D'] = 500;
        RM['M'] = 1000;
        // 开始转换
        for (int i = 0; i < ss.size(); i++) {

            if (i < ss.size() - 1 && ss[i] == 'I' && (ss[i + 1] == 'V' || ss[i + 1] == 'X')) {
                cv = RM[ss[i + 1]] - 1;
                i++;
            } else if(i < ss.size() - 1 && ss[i] == 'X' &&(ss[i + 1] == 'L' || ss[i + 1] == 'C' )){
                    cv = RM[ss[i + 1]] - 10;
                    i++;

            }else if(i < ss.size() - 1 && ss[i] == 'C' &&(ss[i + 1] == 'D' || ss[i + 1] == 'M' )){
                     cv = RM[ss[i + 1]] - 100;
                    i++;
            }else {
                // 当前值
                cv = RM[ss[i]];
            }
            ans += cv;
        }
        return ans;
    }
};

 看了看题解,发现有一个本质:“当前位置的元素比下个位置的元素小,就减去当前值,否则加上当前值”。有了这个,就能优化代码

class Solution {
public:
    int romanToInt(string s) {
        unordered_map<char, int> RM;
        vector<char> ss(s.begin(), s.end());
        int ans = 0;
        int n = ss.size();
        // 初始化
        RM['I'] = 1;
        RM['V'] = 5;
        RM['X'] = 10;
        RM['L'] = 50;
        RM['C'] = 100;
        RM['D'] = 500;
        RM['M'] = 1000;

        for(int i =0;i < n;++i){
            int v = RM[ss[i]];
            if(i < n - 1 && v < RM[ss[i+1]]){
                ans -= v;
            }else{
                ans += v;
            }
        }
        return ans;

    }
};

知识点总结:哈希表、数字、字符串


2、Leetcode-面试经典150题目18-12. 整数转罗马数字

思路:

1、举一个例子num =1994

  •   先将所有字符的可能性列出来,并且按照从大到小的顺序

  •   {1000, "M"},

        {900,  "CM"},

        {500,  "D"},

        {400,  "CD"},

        {100,  "C"},

        {90,   "XC"},

        {50,   "L"},

        {40,   "XL"},

        {10,   "X"},

        {9,    "IX"},

        {5,    "V"},

        {4,    "IV"},

        {1,    "I"},

    };

  • 每次分解的时候选择尽可能大。比如1994,先遍历键值对(1)1994 > 1000,将M放进答案,1994-1000.(2)994 > 900 ,可以,将CM放进答案,994-900 (3)94 < 500,继续遍历 (4)94 < 400,继续遍历 (5)94 < 100,继续遍历  (6) 94 > 50,将L放进答案,94-50 (7) 44  > 40 ,将XL放进答案,44-10 (8)4 < 9 继续遍历  (9) 4 >= 4,将IV放进答案 4-4 =0 退出循环 ,完成。

const pair<int, string> vs[] = {
    {1000, "M"}, {900, "CM"}, {500, "D"}, {400, "CD"}, {100, "C"},
    {90, "XC"},  {50, "L"},   {40, "XL"}, {10, "X"},   {9, "IX"},
    {5, "V"},    {4, "IV"},   {1, "I"},
};

class Solution {
public:
    string intToRoman(int num) {
        string ans = "";
        

            for (int i = 0; i < size(vs); i++) {
                while (num >= vs[i].first) {
                    num -= vs[i].first;
                    ans += vs[i].second;
                }

                if(num ==0 )break;
            }
        

        return ans;
    }

}
;

知识点总结:哈希表、数学、字符串


每日一言:成功的秘诀在于始终坚持不懈,即使在最艰难的时刻,也要保持勇气和希望。

2024年4月2日

softdream

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值