zoukankan      html  css  js  c++  java
  • LeetCode(C++)刷题计划:12-整数转罗马数字

    12-整数转罗马数字

    @Author:CSU张扬
    @Email:csuzhangyang@gmail.com or csuzhangyang@qq.com

    1. 题目

    罗马数字包含以下七种字符: IVXLCDM

    字符          数值
    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 到 3999 的范围内。

    示例 1:
    输入: 3
    输出: "III"
    
    示例 2:
    输入: 4
    输出: "IV"
    
    示例 3:
    输入: 9
    输出: "IX"
    
    示例 4:
    输入: 58
    输出: "LVIII"
    解释: L = 50, V = 5, III = 3.
    
    示例 5:
    输入: 1994
    输出: "MCMXCIV"
    解释: M = 1000, CM = 900, XC = 90, IV = 4.
    

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/integer-to-roman/

    2. 解法

    2.1 解法一:字典寻找法

    1. 我们将个、十、百、千位所有可能出现的数字的罗马字母都罗列出来,然后求出所求数字的个、十、百、千位的值,找出对应的罗马字母即可。

    执行用时: 8 ms, 在所有 cpp 提交中击败了91.78%的用户
    内存消耗: 8.3 MB, 在所有 cpp 提交中击败了90.53%的用户

    class Solution {
    public:
        string intToRoman(int num) {
            string ge[10] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
            string shi[10] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
            string bai[10] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
            string qian[4] = {"", "M", "MM", "MMM"};
            return qian[num / 1000] + bai[(num % 1000) / 100] + shi[(num % 100) / 10] + ge[num % 10];
        }
    };
    

    2.2 解法二:贪心算法

    1. 我们列出所有最小单位的罗马字母组合,假设输入整数为 num
    2. 从最大的数开始匹配,看 num 能匹配几次,每次匹配 num 都要减去这个数。
    3. num 开始小于最大的数,则从第二大的数再次开始匹配,直至 num 变为 0

    我给出两种代码,一种是利用反向迭代器,一种利用普通迭代器,主要是为了熟悉迭代器操作。

    执行用时 :28 ms, 在所有 cpp 提交中击败了22.65%的用户
    内存消耗 :15.3 MB, 在所有 cpp 提交中击败了70.87%的用户

    1 反向迭代器

    class Solution {
    public:
        string intToRoman(int num) {
            map<int, string> romanMap= { {1, "I"}, {4, "IV"}, {5, "V"}, {9, "IX"},
                                         {10, "X"}, {40, "XL"}, {50, "L"}, {90, "XC"},
                                         {100, "C"}, {400, "CD"}, {500, "D"}, {900, "CM"},
                                         {1000, "M"} };
            map<int, string>::reverse_iterator r_iter = romanMap.rbegin();
            string res = "";
            while (r_iter != romanMap.rend()) {
                if (num >= r_iter->first) {
                    res += r_iter->second;
                    num -= r_iter->first;
                }
                else
                    r_iter ++;
            }
            return res;
        }
    };
    

    2 普通迭代器

    class Solution {
    public:
        string intToRoman(int num) {
            map<int, string> romanMap= { {1, "I"}, {4, "IV"}, {5, "V"}, {9, "IX"},
                                         {10, "X"}, {40, "XL"}, {50, "L"}, {90, "XC"},
                                         {100, "C"}, {400, "CD"}, {500, "D"}, {900, "CM"},
                                         {1000, "M"} };
            auto iter = -- romanMap.end();
            string res = "";
            while (iter != -- romanMap.begin()) {
                if (num >= iter->first) {
                    res += iter->second;
                    num -= iter->first;
                }
                else
                    -- iter;
            }
            return res;
        }
    };
    
  • 相关阅读:
    BZOJ-1034-[ZJOI2008]泡泡堂BNB(贪心)
    BZOJ-2456-mode(思维题)
    POJ-2528-Mayor's posters(线段树+离散化)
    POJ-2352-Stars(树状数组)
    HDU-2688-Rotate(树状数组)
    POJ-1195-Mobile phones(二维树状数组)
    YYHS-NOIP2017Training0921-逆光
    YYHS-鏖战字符串(斜率优化)
    左偏树
    2-sat模板
  • 原文地址:https://www.cnblogs.com/MagicConch/p/12179158.html
Copyright © 2011-2022 走看看