Difficulty: Easy, Asked-in: Amazon, Microsoft, Facebook
Key takeaway: An excellent problem to learn problem-solving using loop.
Given a Roman numeral, write a program to find its corresponding decimal value. Roman numerals are represented by seven different symbols:
Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
Example 1: Input: XL, Output: 40
Explanation: XL is a Roman symbol which represents 40
Example 2: Input: MCMIV, Output: 1904
Explanation: M = 1000, CM = 900, IV = 4
Example 3: Input: LVIII, Output: 58
Explanation: L = 50, V= 5, III = 3
Example 4: Input: MCMXCIV, Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4
According to the properties of the Roman numbers, two conditions will appear for any substring of the given input:
One solution idea would be to scan the input string and incrementally generate the integer value based on the appearance of case 1 and case 2 . Suppose function romanToInteger(String S, int n) is converting a roman string S of size n to its integer value.
Step 1: We declare variable output to store the integer value of the given roman string.
Step 2: Now we scan the input string using a loop. Inside the loop: We declare two variables curr and next to track the integer value of two consecutive roman characters at index i and i + 1. We are using a helper function integerValues(char c) to get the integer value of a roman character.
Step 3: By end of the loop, we return the value stored in the variable output.
int integerValue(char c)
{
if (c == 'I')
return 1;
if (c == 'V')
return 5;
if (c == 'X')
return 10;
if (c == 'L')
return 50;
if (c == 'C')
return 100;
if (c == 'D')
return 500;
if (c == 'M')
return 1000;
return -1;
}
int romanToInteger(string S, int n)
{
int output = 0;
for (int i = 0; i < n; i = i + 1)
{
int curr = integerValue(S[i]);
if (i + 1 < n)
{
int next = integerValue(S[i + 1]);
if (curr >= next)
output = output + curr;
else
{
output = output + next - curr;
i = i + 1;
}
}
else
output = output + curr;
}
return output;
}
def integerValue(c):
if c == 'I':
return 1
if c == 'V':
return 5
if c == 'X':
return 10
if c == 'L':
return 50
if c == 'C':
return 100
if c == 'D':
return 500
if c == 'M':
return 1000
return -1
def romanToInteger(S, n):
output = 0
for i in range(n):
curr = integerValue(S[i])
if i + 1 < n:
next = integerValue(S[i + 1])
if curr >= next:
output = output + curr
else:
output = output + next - curr
i = i + 1
else:
output = output + curr
return output
From the Roman string of a number, we can observe one thing: there is only one smaller number before a larger number. Or in other words, there will be at max two Roman characters will be in increasing order. So another basic idea would be:
int integerValue(char c)
{
if (c == 'I')
return 1;
if (c == 'V')
return 5;
if (c == 'X')
return 10;
if (c == 'L')
return 50;
if (c == 'C')
return 100;
if (c == 'D')
return 500;
if (c == 'M')
return 1000;
return -1;
}
int romanToInteger(string S, int n)
{
int output = 0;
for(int i = 0; i < n; i = i + 1)
{
int curr = integerValue(S[i]);
if(i + 1 < n)
{
int next = integerValue (S[i+1]);
if(curr >= next)
output = output + curr;
else
output = output - curr;
}
else
output = output + curr;
}
return output;
}
def integerValue(c):
if c == 'I':
return 1
if c == 'V':
return 5
if c == 'X':
return 10
if c == 'L':
return 50
if c == 'C':
return 100
if c == 'D':
return 500
if c == 'M':
return 1000
return -1
def romanToInteger(S, n):
output = 0
for i in range(n):
curr = integerValue(S[i])
if i + 1 < n:
next = integerValue(S[i + 1])
if curr >= next:
output = output + curr
else:
output = output - curr
else:
output = output + curr
return output
In both approaches, we are running a single loop and doing O(1) operations at each iteration. So time complexity = n * O(1) = O(n). We are using a constant number of variables, so space complexity = O(1).
Enjoy learning, Enjoy algorithms!