盛夏的果实 发表于 2021-8-3 13:37:00

【LeetCode每日一题】12. 整数转罗马数字

【LeetCode每日一题】12. 整数转罗马数字题目:罗马数字包含以下七种字符:I, V, X, L,C,D 和 M。
字符          数值
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:
输入: num = 3
输出: "III"
题解:
下面将会展示两种方法,而这两种方法都是基于右区间压缩方法,不断贪心,右边大的数使用过之后,不会再进行选择,因此每次查找的数据范围依次缩小,例如第一次13个数,第二次有可能就变成11个数,依次类推。
第一种思路是贪心策略+枚举模拟
实现如下,具体可以对应到第二种方法注释部分代码。
for (int i = nums.size() - 1; i >= 0; i--) {
    while (num >= nums) {
        num -= nums;
        ans += m];
    }
}
第二种思路是二分查找法去查找小于等于当前数的元素。
class Solution {
public:
    string intToRoman(int num) {
        map<int, string> m{
            {4, "IV"},{9, "IX"},{40, "XL"},{90, "XC"},{400, "CD"},{900, "CM"},
            {1, "I"}, {5, "V"}, {10, "X"}, {50, "L"}, {100, "C"}, {500, "D"}, {1000, "M"}
        };

        string ans;
        vector<int> nums{1,4,5,9,10,40,50,90,100,400,500,900,1000};
        int r = nums.size() - 1;
        while (num) {
            int l = bs(nums, num, r);
            int chu = num / nums, yu = num % nums;
            for (int i = 0; i < chu; i++) {
                ans += m];
            }
            num = yu;
            r = l - 1;
        }
        // for (int i = nums.size() - 1; i >= 0; i--) {
        //     while (num >= nums) {
        //         num -= nums;
        //         ans += m];
        //     }
        // }
        return ans;
    }
    // 查找第一个小于等于x的数
    int bs(vector<int>& nums, int target, int r) {
        int l = 0;
        while (l < r) {
            int mid = l + r + 1 >> 1;
            if (nums <= target) {
                l = mid;
            } else {
                r = mid - 1;
            }
        }
        return l;
    }
};
本节完~



文档来源:51CTO技术博客https://blog.51cto.com/u_12205414/3252067
页: [1]
查看完整版本: 【LeetCode每日一题】12. 整数转罗马数字