3

Question: Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.

Symbol       Value
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II.

Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:

I can be placed before V (5) and X (10) to make 4 and 9. X can be placed before L (50) and C (100) to make 40 and 90. C can be placed before D (500) and M (1000) to make 400 and 900. Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999.

Example 1: Input: 3 Output: "III"

Example 2: Input: 4 Output: "IV"

Example 3: Input: 9 Output: "IX"

Example 4: Input: 58 Output: "LVIII" Explanation: L = 50, V = 5, III = 3.

Example 5: Input: 1994 Output: "MCMXCIV" Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.


Answer:

#include <unordered_map>
using namespace std;

class Solution {
    public:
        string intToRoman(int num) {
            
            /*
                Symbol       Value
                I             1
                IV            4
                V             5
                IX            9
                X             10
                XL            40
                L             50
                XC            90
                C             100
                CD            400
                D             500
                CM            900
                M             1000      
            */
         
            vector<string> romanStr {"I", "IV", "V", "IX", "X", "XL", 
                                     "L", "XC", "C", "CD", "D", "CM", "M"};
            vector<int> numVals {1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000};
            
            string roman;
            
                while (num != 0) {

                    for (int i = numVals.size() - 1; i >= 0; i--) {

                        if (num - numVals.at(i) < 0) continue;

                        num -= numVals.at(i);
                        roman += romanStr.at(i);

                        break;
                    }

                }
            
            return roman;
            
            
        }
};

This code converts an integer to it's roman numeral equivalent. But I am unsure if it is O(1) or O(N) time complexity where N is the value of num. I think it's O(N) because the number of iterations depends on the value of num?

csguy
  • 1,354
  • 2
  • 17
  • 37
  • https://en.wikipedia.org/wiki/Roman_numerals , it seems there are many variants, can you give some examples or tell what variant are you trying to implement? – รยקคгรђשค Oct 01 '20 at 02:24
  • @รยקคгรђשค full question posted with examples, but im just interested in the runtime of said code – csguy Oct 01 '20 at 04:17
  • 1
    Its O(N) in general, but considering the input size is very small it would be O(1) specifically. If you were to implement this for arbitrarily big number, the implementation I can think is possible in O(N*logN) and not O(N). Here N is the value of number. If we consider digits present in N, then it would be exponential. – รยקคгรђשค Oct 01 '20 at 04:36

2 Answers2

-1

It is O(n) as for a very big number n you would need n/1000 many Ms. Remember, we are interested im arbitrarily large number. O(n/1000) = O(n). Also mind that this should be considered exponential, as n can be encoded by O(log n) bits. For a finite set of inputs it would obviously be O(1) as stated in the comments.

andrbrue
  • 721
  • 6
  • 15
  • What do you think about the O(1) claim https://leetcode.com/problems/integer-to-roman/solution/ – csguy Oct 01 '20 at 01:39
  • 1
    I cannot see this claim as an anonymous user. But mind that they say "Input is guaranteed to be within the range from 1 to 3999.". This implies a finite set of inputs which render the O notation irrelevant as it is O(1) for every problem with only finite many inputs. – andrbrue Oct 01 '20 at 01:43
  • Can you elaborate on how do you think it is exponential? – รยקคгรђשค Oct 01 '20 at 02:59
  • Usually you analyse the growth depending on the input size. Having n as input it is to be assumed that we use e. g. binary encoding yielding an input length of m = Θ(log n). Then our complexity is O(n) = O(exp(m)). – andrbrue Oct 01 '20 at 11:22
  • @andrbrue It lacks clear explanation of your complexity. Also for an arbitrarily big number your complexity seems incorrect. Think about what other operations are involved like subtraction or addition. I think it should be O(N*LogN) where N is the number, if you give a good explanation of why you can do it in O(N) or O(NLogN) or whatever your claim is, I will remove my downvote, and turn it to upvote. I agree that it is exponential in the digits space i.e. O(digits*10^digits). – รยקคгรђשค Oct 01 '20 at 12:28
  • I think that it just depends on what you decide to count as elementary operation. Usually when analyzing an algorithm you count high level operations like comparisions or arithmetic operations. But I agree that on a lower level (extreme case would be Turing Machine) we had to count log n for the subtraction. It may be inconsistent on my side to use the digit space for n and simultaneously switch to a higher level when choosing which operations to count. – andrbrue Oct 01 '20 at 13:10
  • @andrbrue We should only ignore cost of operations like addition, subtraction, etc. when our target bit space is fixed as they can be considered constants and so will be the order of runtime for a fixed bit space, i.e. 32 bits or 64 bits or 128 bits these are constants. I received the impression from your answer that you are considering "very big number" as numbers for which bits space is not fixed, which you apparently aren't. Its nothing wrong to consider digit space for numbers if you are doing it right. – รยקคгรђשค Oct 01 '20 at 13:49
  • I have answered something similar here https://stackoverflow.com/questions/61960113/subtle-nuances-of-big-o-notation-for-computation-complexity @csguy – Ido Oct 02 '20 at 15:12
-2

Becuase the input is guaranteed to be within the range from 1 to 3999, we can just call it O(1), becuase the question doesn't even matter for 'big n'. (anyway, its not such an intersting question for time complexity analysis becuase of this, and I kindly suggest you just move on.)

Ido
  • 92
  • 8