评论

收藏

[C++] 【LeetCode每日一题】12. 整数转罗马数字

编程语言 编程语言 发布于:2021-08-03 13:37 | 阅读数:379 | 评论:0

【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[i]) {
        num -= nums[i];
        ans += m[nums[i]];
    }
}
第二种思路是二分查找法去查找小于等于当前数的元素。
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[l], yu = num % nums[l];
            for (int i = 0; i < chu; i++) {
                ans += m[nums[l]];
            }
            num = yu;
            r = l - 1;
        }
        // for (int i = nums.size() - 1; i >= 0; i--) {
        //     while (num >= nums[i]) {
        //         num -= nums[i];
        //         ans += m[nums[i]];
        //     }
        // }
        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[mid] <= target) {
                l = mid;
            } else {
                r = mid - 1;
            }
        }
        return l;
    }
};
本节完~



关注下面的标签,发现更多相似文章